[cfe-commits] r70545 - /cfe/trunk/lib/Analysis/BugReporter.cpp
Ted Kremenek
kremenek at apple.com
Fri May 1 09:08:09 PDT 2009
Author: kremenek
Date: Fri May 1 11:08:09 2009
New Revision: 70545
URL: http://llvm.org/viewvc/llvm-project?rev=70545&view=rev
Log:
BugReporter (extensive diagnostics): introduce the notion of a "dead"
location context. This allows us to postpone the decision of whether
or not a context should add a control-flow piece to the diagnostics
when inspecting its subexpressions.
Modified:
cfe/trunk/lib/Analysis/BugReporter.cpp
Modified: cfe/trunk/lib/Analysis/BugReporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/BugReporter.cpp?rev=70545&r1=70544&r2=70545&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/BugReporter.cpp (original)
+++ cfe/trunk/lib/Analysis/BugReporter.cpp Fri May 1 11:08:09 2009
@@ -757,21 +757,33 @@
}
namespace {
+class VISIBILITY_HIDDEN ContextLocation : public PathDiagnosticLocation {
+ bool IsDead;
+public:
+ ContextLocation(const PathDiagnosticLocation &L, bool isdead = false)
+ : PathDiagnosticLocation(L), IsDead(isdead) {}
+
+ void markDead() { IsDead = true; }
+ bool isDead() const { return IsDead; }
+};
+
class VISIBILITY_HIDDEN EdgeBuilder {
- std::vector<PathDiagnosticLocation> CLocs;
- typedef std::vector<PathDiagnosticLocation>::iterator iterator;
+ std::vector<ContextLocation> CLocs;
+ typedef std::vector<ContextLocation>::iterator iterator;
PathDiagnostic &PD;
PathDiagnosticBuilder &PDB;
PathDiagnosticLocation PrevLoc;
-
+
+ bool IsConsumedExpr(const PathDiagnosticLocation &L);
+
bool containsLocation(const PathDiagnosticLocation &Container,
const PathDiagnosticLocation &Containee);
PathDiagnosticLocation getContextLocation(const PathDiagnosticLocation &L);
void popLocation() {
- PathDiagnosticLocation L = CLocs.back();
- if (L.asLocation().isFileID()) {
+ if (!CLocs.back().isDead() && CLocs.back().asLocation().isFileID()) {
+ PathDiagnosticLocation L = CLocs.back();
if (const Stmt *S = L.asStmt()) {
while (1) {
@@ -938,20 +950,30 @@
const PathDiagnosticLocation &CLoc = getContextLocation(NewLoc);
while (!CLocs.empty()) {
- const PathDiagnosticLocation &TopContextLoc = CLocs.back();
+ ContextLocation &TopContextLoc = CLocs.back();
// Is the top location context the same as the one for the new location?
if (TopContextLoc == CLoc) {
- if (alwaysAdd)
+ if (alwaysAdd) {
+ if (IsConsumedExpr(TopContextLoc))
+ TopContextLoc.markDead();
+
rawAddEdge(NewLoc);
+ }
return;
}
if (containsLocation(TopContextLoc, CLoc)) {
- if (alwaysAdd)
+ if (alwaysAdd) {
rawAddEdge(NewLoc);
-
+
+ if (IsConsumedExpr(CLoc)) {
+ CLocs.push_back(ContextLocation(CLoc, true));
+ return;
+ }
+ }
+
CLocs.push_back(CLoc);
return;
}
@@ -964,6 +986,13 @@
rawAddEdge(NewLoc);
}
+bool EdgeBuilder::IsConsumedExpr(const PathDiagnosticLocation &L) {
+ if (const Expr *X = dyn_cast_or_null<Expr>(L.asStmt()))
+ return PDB.getParentMap().isConsumedExpr(X) && !IsControlFlowExpr(X);
+
+ return false;
+}
+
void EdgeBuilder::addContext(const Stmt *S) {
if (!S)
return;
@@ -1040,8 +1069,10 @@
if (const BlockEntrance *BE = dyn_cast<BlockEntrance>(&P)) {
if (const Stmt* S = BE->getFirstStmt()) {
- if (IsControlFlowExpr(S))
+ if (IsControlFlowExpr(S)) {
+ // Add the proper context for '&&', '||', and '?'.
EB.addContext(S);
+ }
else
EB.addContext(PDB.getEnclosingStmtLocation(S).asStmt());
}
More information about the cfe-commits
mailing list