[cfe-commits] r49077 - /cfe/trunk/lib/Analysis/GRSimpleVals.cpp

Ted Kremenek kremenek at apple.com
Tue Apr 1 22:15:22 PDT 2008


Author: kremenek
Date: Wed Apr  2 00:15:22 2008
New Revision: 49077

URL: http://llvm.org/viewvc/llvm-project?rev=49077&view=rev
Log:
Added initial hacked support for display path diagnostics with
GRSimpleVals warnings.  Cleaning up, but now we get multiple bubbles (branches are annotated).

Modified:
    cfe/trunk/lib/Analysis/GRSimpleVals.cpp

Modified: cfe/trunk/lib/Analysis/GRSimpleVals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRSimpleVals.cpp?rev=49077&r1=49076&r2=49077&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/GRSimpleVals.cpp (original)
+++ cfe/trunk/lib/Analysis/GRSimpleVals.cpp Wed Apr  2 00:15:22 2008
@@ -24,12 +24,23 @@
 namespace clang {
 
 template <typename ITERATOR>
+static inline ExplodedNode<ValueState>* GetNode(ITERATOR I) {
+  return *I;
+}
+
+template <>
+static inline ExplodedNode<ValueState>*
+GetNode(GRExprEngine::undef_arg_iterator I) {
+  return I->first;
+}
+  
+template <typename ITERATOR>
 static inline ProgramPoint GetLocation(ITERATOR I) {
   return (*I)->getLocation();
 }
   
 template <>
-inline ProgramPoint GetLocation(GRExprEngine::undef_arg_iterator I) {
+static inline ProgramPoint GetLocation(GRExprEngine::undef_arg_iterator I) {
   return I->first->getLocation();
 }
   
@@ -44,7 +55,93 @@
   assert (false && "Unsupported ProgramPoint.");
   return NULL;
 }
+  
+  
+//===----------------------------------------------------------------------===//
+// Path Warnings.
+//===----------------------------------------------------------------------===//
+
+static inline SourceLocation GetSourceLoc(ProgramPoint P) {
+  
+  if (const PostStmt* PS = dyn_cast<PostStmt>(&P)) {
+    return PS->getStmt()->getLocStart();
+  }
+  else if (const BlockEdge* BE = dyn_cast<BlockEdge>(&P)) {
+    return BE->getSrc()->getTerminator()->getLocStart();
+  }
+  
+  return SourceLocation();
+}
+  
+static inline
+FullSourceLoc GetFullSourceLoc(SourceManager& SMgr, ProgramPoint P) {
+  return FullSourceLoc(GetSourceLoc(P), SMgr);  
+}
+  
+template <typename ITERATOR>
+static void EmitPathWarning(Diagnostic& Diag, PathDiagnosticClient* PD,
+                            SourceManager& SrcMgr, const std::string& msg,
+                            ITERATOR I) {
+  
+  
+  PathDiagnostic D;
+
+  { // Add the end message.
+   
+    ProgramPoint P = GetLocation(I);
+    D.push_back(new PathDiagnosticPiece(GetFullSourceLoc(SrcMgr, P), msg));
+  }
+  
+  // Walk up the path.
+  
+  ExplodedNode<ValueState> *N = GetNode(I);
+  
+  while (N) {
+    
+    if (N->pred_empty())
+      break;
+    
+    N = *(N->pred_begin()); // Grab the first predecessor.
+    
+    ProgramPoint P = N->getLocation();
+    
+    if (const BlockEdge* BE = dyn_cast<BlockEdge>(&P)) {
+      
+      CFGBlock* Src = BE->getSrc();
+      CFGBlock* Dst = BE->getDst();
+      
+      // FIXME: Better handling for switches.
+      
+      if (Src->succ_size() == 2) {
+        
+        Stmt* T = Src->getTerminator();
+        
+        if (!Src)
+          continue;
+        
+        if (*(Src->succ_begin()+1) == Dst) {
+          D.push_front(new PathDiagnosticPiece(FullSourceLoc(T->getLocStart(),
+                                                          SrcMgr),
+                                            "Taking false branch."));
+        
+        }
+        else {
+          D.push_front(new PathDiagnosticPiece(FullSourceLoc(T->getLocStart(),
+                                                            SrcMgr),
+                                              "Taking true branch."));
+        }
+      }
+    }
+  }
+  
+  // Emit the path.
+  PD->HandlePathDiagnostic(D);                                    
+}
 
+//===----------------------------------------------------------------------===//
+// Pathless Warnings
+//===----------------------------------------------------------------------===//
+  
 template <typename ITERATOR>
 static void EmitDiag(Diagnostic& Diag, PathDiagnosticClient* PD,
                      SourceManager& SrcMgr,
@@ -76,7 +173,7 @@
                  ITERATOR I, ITERATOR E, const char* msg) {
  
   std::ostringstream Out;
-  std::string Str;
+  std::string Str(msg);
 
   if (!PD) {
     Out << "[CHECKER] " << msg;
@@ -107,10 +204,17 @@
       CachedErrors.insert(p);
     }
     
-    EmitDiag(Diag, PD, SrcMgr, ErrorDiag, I);  
+    if (PD)
+      EmitPathWarning(Diag, PD, SrcMgr, Str, I);
+    else
+      EmitDiag(Diag, PD, SrcMgr, ErrorDiag, I);  
   }
 }
   
+//===----------------------------------------------------------------------===//
+// Analysis Driver.
+//===----------------------------------------------------------------------===//
+  
 unsigned RunGRSimpleVals(CFG& cfg, Decl& CD, ASTContext& Ctx,
                          Diagnostic& Diag, PathDiagnosticClient* PD,
                          bool Visualize, bool TrimGraph) {





More information about the cfe-commits mailing list