[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