[cfe-commits] r79302 - in /cfe/trunk: include/clang/Analysis/PathSensitive/BugReporter.h include/clang/Analysis/PathSensitive/Checker.h lib/Analysis/BugReporter.cpp lib/Analysis/BugReporterVisitors.cpp lib/Analysis/GRExprEngineInternalChecks.cpp

Ted Kremenek kremenek at apple.com
Mon Aug 17 18:05:31 PDT 2009


Author: kremenek
Date: Mon Aug 17 20:05:30 2009
New Revision: 79302

URL: http://llvm.org/viewvc/llvm-project?rev=79302&view=rev
Log:
Enhance static analyzer diagnostics by introducing a new 'EnhancedBugReporter'
which allows custom checks to register callback creator functions for creating
BugReporterVisitor objects. This allows various checks to include diagnostics
such as 'assuming value is null' with little extra work. Eventually this API
should be refactored to be cleaner and more simple.

Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h
    cfe/trunk/include/clang/Analysis/PathSensitive/Checker.h
    cfe/trunk/lib/Analysis/BugReporter.cpp
    cfe/trunk/lib/Analysis/BugReporterVisitors.cpp
    cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h?rev=79302&r1=79301&r2=79302&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/BugReporter.h Mon Aug 17 20:05:30 2009
@@ -244,6 +244,35 @@
   }
 };
   
+class EnhancedBugReport : public RangedBugReport {
+public:
+  typedef void (*VisitorCreator)(BugReporterContext &BRcC, const void *data,
+                                 const ExplodedNode *N);
+  
+private:
+  typedef std::vector<std::pair<VisitorCreator, const void*> > Creators;
+  Creators creators;
+  
+public:
+  EnhancedBugReport(BugType& D, const char* description, ExplodedNode *n)
+   : RangedBugReport(D, description, n) {}
+  
+  EnhancedBugReport(BugType& D, const char *shortDescription,
+                  const char *description, ExplodedNode *n)
+    : RangedBugReport(D, shortDescription, description, n) {}
+  
+  ~EnhancedBugReport() {}
+  
+  void registerInitialVisitors(BugReporterContext& BRC, const ExplodedNode* N) {    
+    for (Creators::iterator I = creators.begin(), E = creators.end(); I!=E; ++I)
+      I->first(BRC, I->second, N);
+  }
+  
+  void addVisitorCreator(VisitorCreator creator, const void *data) {
+    creators.push_back(std::make_pair(creator, data));
+  }
+};
+  
 //===----------------------------------------------------------------------===//
 // BugReporter and friends.
 //===----------------------------------------------------------------------===//
@@ -471,7 +500,7 @@
 const Stmt *GetCalleeExpr(const ExplodedNode *N);
 const Stmt *GetRetValExpr(const ExplodedNode *N);
 
-void registerTrackNullOrUndefValue(BugReporterContext& BRC, const Stmt *S,
+void registerTrackNullOrUndefValue(BugReporterContext& BRC, const void *stmt,
                                    const ExplodedNode* N);
 
 } // end namespace clang::bugreporter

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/Checker.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/Checker.h?rev=79302&r1=79301&r2=79302&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/Checker.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/Checker.h Mon Aug 17 20:05:30 2009
@@ -17,6 +17,7 @@
 #include "clang/Analysis/Support/SaveAndRestore.h"
 #include "clang/Analysis/PathSensitive/GRCoreEngine.h"
 #include "clang/Analysis/PathSensitive/GRState.h"
+#include "clang/Analysis/PathSensitive/GRExprEngine.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/StmtCXX.h"
@@ -67,9 +68,18 @@
   ExplodedNode *&getPredecessor() { return Pred; }
   const GRState *getState() { return B.GetState(Pred); }
   
-  ExplodedNode *generateNode(const Stmt* S,
-                                      const GRState *state) {
-    return B.generateNode(S, state, Pred);
+  ASTContext &getASTContext() {
+    return Eng.getContext();
+  }
+  
+  ExplodedNode *generateNode(const Stmt* S, const GRState *state,
+                             bool markAsSink = false) {    
+    ExplodedNode *node = B.generateNode(S, state, Pred);
+    
+    if (markAsSink && node)
+      node->markAsSink();
+    
+    return node;
   }
   
   void addTransition(ExplodedNode *node) {

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

==============================================================================
--- cfe/trunk/lib/Analysis/BugReporter.cpp (original)
+++ cfe/trunk/lib/Analysis/BugReporter.cpp Mon Aug 17 20:05:30 2009
@@ -41,8 +41,8 @@
 //===----------------------------------------------------------------------===//
 
 static inline const Stmt* GetStmt(ProgramPoint P) {
-  if (const PostStmt* PS = dyn_cast<PostStmt>(&P))
-    return PS->getStmt();
+  if (const StmtPoint* SP = dyn_cast<StmtPoint>(&P))
+    return SP->getStmt();
   else if (const BlockEdge* BE = dyn_cast<BlockEdge>(&P))
     return BE->getSrc()->getTerminator();
   

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

==============================================================================
--- cfe/trunk/lib/Analysis/BugReporterVisitors.cpp (original)
+++ cfe/trunk/lib/Analysis/BugReporterVisitors.cpp Mon Aug 17 20:05:30 2009
@@ -189,6 +189,10 @@
       else if (V.isUndef()) {
         os << "Uninitialized value stored to ";
       }
+      else if (isa<nonloc::ConcreteInt>(V)) {
+        os << "The value " << cast<nonloc::ConcreteInt>(V).getValue()
+           << " is assigned to ";
+      }
       else
         return NULL;
       
@@ -296,9 +300,11 @@
 }
 
 void clang::bugreporter::registerTrackNullOrUndefValue(BugReporterContext& BRC,
-                                                       const Stmt *S,
+                                                       const void *data,
                                                        const ExplodedNode* N) {
   
+  const Stmt *S = static_cast<const Stmt*>(data);
+  
   if (!S)
     return;
   

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

==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngineInternalChecks.cpp Mon Aug 17 20:05:30 2009
@@ -583,7 +583,7 @@
       if (stateNull && !stateNotNull) {
         // Generate an error node.  Check for a null node in case
         // we cache out.
-        if (ExplodedNode *errorNode = C.generateNode(CE, stateNull)) {
+        if (ExplodedNode *errorNode = C.generateNode(CE, stateNull, true)) {
                   
           // Lazily allocate the BugType object if it hasn't already been
           // created. Ownership is transferred to the BugReporter object once
@@ -592,12 +592,15 @@
             BT = new BugType("Argument with 'nonnull' attribute passed null",
                              "API");
           
-          RangedBugReport *R =
-            new RangedBugReport(*BT, "Null pointer passed as an argument to a "
-                                "'nonnull' parameter", errorNode);
+          EnhancedBugReport *R =
+            new EnhancedBugReport(*BT,
+                                  "Null pointer passed as an argument to a "
+                                  "'nonnull' parameter", errorNode);
           
           // Highlight the range of the argument that was null.
-          R->addRange((*I)->getSourceRange());
+          const Expr *arg = *I;
+          R->addRange(arg->getSourceRange());
+          R->addVisitorCreator(registerTrackNullOrUndefValue, arg);
           
           // Emit the bug report.
           C.EmitReport(R);





More information about the cfe-commits mailing list