[cfe-commits] r112789 - in /cfe/trunk: include/clang/Checker/PathSensitive/Checker.h include/clang/Checker/PathSensitive/GRExprEngine.h lib/Checker/GRExprEngine.cpp lib/Checker/MallocChecker.cpp lib/Checker/UndefinedAssignmentChecker.cpp test/Analysis/plist-output.m

Ted Kremenek kremenek at apple.com
Wed Sep 1 17:56:20 PDT 2010


Author: kremenek
Date: Wed Sep  1 19:56:20 2010
New Revision: 112789

URL: http://llvm.org/viewvc/llvm-project?rev=112789&view=rev
Log:
For GRExprEngine::EvalBind() (and called visitors), unifiy StoreE and AssignE.  Now StoreE (const Stmt*) represents the expression where the store took place, which is the assignment expression if it takes place in an assignment.  This removes some conceptual dissidence as well as removes an extra parameter from the Checker::PreVisitBind() visitor.  It also improves ranges and source location information in analyzer diagnostics.

Modified:
    cfe/trunk/include/clang/Checker/PathSensitive/Checker.h
    cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h
    cfe/trunk/lib/Checker/GRExprEngine.cpp
    cfe/trunk/lib/Checker/MallocChecker.cpp
    cfe/trunk/lib/Checker/UndefinedAssignmentChecker.cpp
    cfe/trunk/test/Analysis/plist-output.m

Modified: cfe/trunk/include/clang/Checker/PathSensitive/Checker.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Checker/PathSensitive/Checker.h?rev=112789&r1=112788&r2=112789&view=diff
==============================================================================
--- cfe/trunk/include/clang/Checker/PathSensitive/Checker.h (original)
+++ cfe/trunk/include/clang/Checker/PathSensitive/Checker.h Wed Sep  1 19:56:20 2010
@@ -226,7 +226,6 @@
   // FIXME: Remove the 'tag' option.
   void GR_VisitBind(ExplodedNodeSet &Dst,
                     GRStmtNodeBuilder &Builder, GRExprEngine &Eng,
-                    const Stmt *AssignE,
                     const Stmt *StoreE, ExplodedNode *Pred, void *tag, 
                     SVal location, SVal val,
                     bool isPrevisit) {
@@ -234,7 +233,7 @@
                      isPrevisit ? ProgramPoint::PreStmtKind :
                      ProgramPoint::PostStmtKind, 0, StoreE);
     assert(isPrevisit && "Only previsit supported for now.");
-    PreVisitBind(C, AssignE, StoreE, location, val);
+    PreVisitBind(C, StoreE, location, val);
   }
   
   // FIXME: Remove the 'tag' option.
@@ -264,8 +263,8 @@
   virtual void _PreVisit(CheckerContext &C, const Stmt *S) {}
   virtual void _PostVisit(CheckerContext &C, const Stmt *S) {}
   virtual void VisitLocation(CheckerContext &C, const Stmt *S, SVal location) {}
-  virtual void PreVisitBind(CheckerContext &C, const Stmt *AssignE,
-                            const Stmt *StoreE, SVal location, SVal val) {}
+  virtual void PreVisitBind(CheckerContext &C, const Stmt *StoreE,
+                            SVal location, SVal val) {}
   virtual void EvalDeadSymbols(CheckerContext &C, SymbolReaper &SymReaper) {}
   virtual void EvalEndPath(GREndPathNodeBuilder &B, void *tag,
                            GRExprEngine &Eng) {}

Modified: cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h?rev=112789&r1=112788&r2=112789&view=diff
==============================================================================
--- cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Checker/PathSensitive/GRExprEngine.h Wed Sep  1 19:56:20 2010
@@ -295,10 +295,9 @@
                               const GRState *state,
                               ExplodedNode *Pred);
   
-  void CheckerVisitBind(const Stmt *AssignE, const Stmt *StoreE,
-                        ExplodedNodeSet &Dst, ExplodedNodeSet &Src, 
-                        SVal location, SVal val, bool isPrevisit);
-
+  void CheckerVisitBind(const Stmt *StoreE, ExplodedNodeSet &Dst,
+                        ExplodedNodeSet &Src,  SVal location, SVal val,
+                        bool isPrevisit);
 
   /// Visit - Transfer function logic for all statements.  Dispatches to
   ///  other functions that handle specific kinds of statements.
@@ -494,8 +493,7 @@
 
   /// EvalBind - Handle the semantics of binding a value to a specific location.
   ///  This method is used by EvalStore, VisitDeclStmt, and others.
-  void EvalBind(ExplodedNodeSet& Dst, const Stmt *AssignE,
-                const Stmt* StoreE, ExplodedNode* Pred,
+  void EvalBind(ExplodedNodeSet& Dst, const Stmt* StoreE, ExplodedNode* Pred,
                 const GRState* St, SVal location, SVal Val,
                 bool atDeclInit = false);
 

Modified: cfe/trunk/lib/Checker/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/GRExprEngine.cpp?rev=112789&r1=112788&r2=112789&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Checker/GRExprEngine.cpp Wed Sep  1 19:56:20 2010
@@ -306,10 +306,9 @@
 
 // FIXME: This is largely copy-paste from CheckerVisit().  Need to
 // unify.
-void GRExprEngine::CheckerVisitBind(const Stmt *AssignE, const Stmt *StoreE,
-                                    ExplodedNodeSet &Dst,
-                                    ExplodedNodeSet &Src,
-                                    SVal location, SVal val, bool isPrevisit) {
+void GRExprEngine::CheckerVisitBind(const Stmt *StoreE, ExplodedNodeSet &Dst,
+                                    ExplodedNodeSet &Src, SVal location,
+                                    SVal val, bool isPrevisit) {
 
   if (Checkers.empty()) {
     Dst.insert(Src);
@@ -334,7 +333,7 @@
 
     for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
          NI != NE; ++NI)
-      checker->GR_VisitBind(*CurrSet, *Builder, *this, AssignE, StoreE,
+      checker->GR_VisitBind(*CurrSet, *Builder, *this, StoreE,
                             *NI, tag, location, val, isPrevisit);
 
     // Update which NodeSet is the current one.
@@ -1816,16 +1815,15 @@
 
 /// EvalBind - Handle the semantics of binding a value to a specific location.
 ///  This method is used by EvalStore and (soon) VisitDeclStmt, and others.
-void GRExprEngine::EvalBind(ExplodedNodeSet& Dst, const Stmt *AssignE,
-                            const Stmt* StoreE, ExplodedNode* Pred,
-                            const GRState* state, SVal location, SVal Val,
-                            bool atDeclInit) {
+void GRExprEngine::EvalBind(ExplodedNodeSet& Dst, const Stmt* StoreE,
+                            ExplodedNode* Pred, const GRState* state,
+                            SVal location, SVal Val, bool atDeclInit) {
 
 
   // Do a previsit of the bind.
   ExplodedNodeSet CheckedSet, Src;
   Src.Add(Pred);
-  CheckerVisitBind(AssignE, StoreE, CheckedSet, Src, location, Val, true);
+  CheckerVisitBind(StoreE, CheckedSet, Src, location, Val, true);
 
   for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
        I!=E; ++I) {
@@ -1858,6 +1856,10 @@
     // The next thing to do is check if the GRTransferFuncs object wants to
     // update the state based on the new binding.  If the GRTransferFunc object
     // doesn't do anything, just auto-propagate the current state.
+    
+    // NOTE: We use 'AssignE' for the location of the PostStore if 'AssignE'
+    // is non-NULL.  Checkers typically care about 
+    
     GRStmtNodeBuilderRef BuilderRef(Dst, *Builder, *this, *I, newState, StoreE,
                                     newState != state);
 
@@ -1872,7 +1874,7 @@
 ///  @param location The location to store the value
 ///  @param Val The value to be stored
 void GRExprEngine::EvalStore(ExplodedNodeSet& Dst, const Expr *AssignE,
-                             const Expr* StoreE,
+                             const Expr* LocationE,
                              ExplodedNode* Pred,
                              const GRState* state, SVal location, SVal Val,
                              const void *tag) {
@@ -1881,7 +1883,7 @@
 
   // Evaluate the location (checks for bad dereferences).
   ExplodedNodeSet Tmp;
-  EvalLocation(Tmp, StoreE, Pred, state, location, tag, false);
+  EvalLocation(Tmp, LocationE, Pred, state, location, tag, false);
 
   if (Tmp.empty())
     return;
@@ -1892,9 +1894,12 @@
                                                    ProgramPoint::PostStoreKind);
   SaveAndRestore<const void*> OldTag(Builder->Tag, tag);
 
-  // Proceed with the store.
+  // Proceed with the store.  We use AssignE as the anchor for the PostStore
+  // ProgramPoint if it is non-NULL, and LocationE otherwise.
+  const Expr *StoreE = AssignE ? AssignE : LocationE;
+
   for (ExplodedNodeSet::iterator NI=Tmp.begin(), NE=Tmp.end(); NI!=NE; ++NI)
-    EvalBind(Dst, AssignE, StoreE, *NI, GetState(*NI), location, Val);
+    EvalBind(Dst, StoreE, *NI, GetState(*NI), location, Val);
 }
 
 void GRExprEngine::EvalLoad(ExplodedNodeSet& Dst, const Expr *Ex, 
@@ -2701,7 +2706,7 @@
                                                Builder->getCurrentBlockCount());
       }
 
-      EvalBind(Dst, DS, DS, *I, state,
+      EvalBind(Dst, DS, *I, state,
                loc::MemRegionVal(state->getRegion(VD, LC)), InitVal, true);
     }
     else {
@@ -2733,7 +2738,7 @@
                                             Builder->getCurrentBlockCount());
     }
 
-    EvalBind(Dst, S, S, N, state,
+    EvalBind(Dst, S, N, state,
              loc::MemRegionVal(state->getRegion(VD, LC)), InitVal, true);
   }
 }

Modified: cfe/trunk/lib/Checker/MallocChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/MallocChecker.cpp?rev=112789&r1=112788&r2=112789&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/MallocChecker.cpp (original)
+++ cfe/trunk/lib/Checker/MallocChecker.cpp Wed Sep  1 19:56:20 2010
@@ -82,9 +82,8 @@
   const GRState *EvalAssume(const GRState *state, SVal Cond, bool Assumption,
                             bool *respondsToCallback);
   void VisitLocation(CheckerContext &C, const Stmt *S, SVal l);
-  virtual void PreVisitBind(CheckerContext &C, const Stmt *AssignE,
-                            const Stmt *StoreE, SVal location,
-                            SVal val);
+  virtual void PreVisitBind(CheckerContext &C, const Stmt *StoreE,
+                            SVal location, SVal val);
 
 private:
   void MallocMem(CheckerContext &C, const CallExpr *CE);
@@ -676,7 +675,6 @@
 }
 
 void MallocChecker::PreVisitBind(CheckerContext &C,
-                                 const Stmt *AssignE,
                                  const Stmt *StoreE,
                                  SVal location,
                                  SVal val) {

Modified: cfe/trunk/lib/Checker/UndefinedAssignmentChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/UndefinedAssignmentChecker.cpp?rev=112789&r1=112788&r2=112789&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/UndefinedAssignmentChecker.cpp (original)
+++ cfe/trunk/lib/Checker/UndefinedAssignmentChecker.cpp Wed Sep  1 19:56:20 2010
@@ -25,9 +25,8 @@
 public:
   UndefinedAssignmentChecker() : BT(0) {}
   static void *getTag();
-  virtual void PreVisitBind(CheckerContext &C, const Stmt *AssignE,
-                            const Stmt *StoreE, SVal location,
-                            SVal val);
+  virtual void PreVisitBind(CheckerContext &C, const Stmt *StoreE,
+                            SVal location, SVal val);
 };
 }
 
@@ -41,7 +40,6 @@
 }
 
 void UndefinedAssignmentChecker::PreVisitBind(CheckerContext &C,
-                                              const Stmt *AssignE,
                                               const Stmt *StoreE,
                                               SVal location,
                                               SVal val) {
@@ -61,8 +59,8 @@
   // Generate a report for this bug.
   const Expr *ex = 0;
 
-  while (AssignE) {
-    if (const BinaryOperator *B = dyn_cast<BinaryOperator>(AssignE)) {
+  while (StoreE) {
+    if (const BinaryOperator *B = dyn_cast<BinaryOperator>(StoreE)) {
       if (B->isCompoundAssignmentOp()) {
         const GRState *state = C.getState();
         if (state->getSVal(B->getLHS()).isUndef()) {
@@ -77,7 +75,7 @@
       break;
     }
 
-    if (const DeclStmt *DS = dyn_cast<DeclStmt>(AssignE)) {
+    if (const DeclStmt *DS = dyn_cast<DeclStmt>(StoreE)) {
       const VarDecl* VD = dyn_cast<VarDecl>(DS->getSingleDecl());
       ex = VD->getInit();
     }

Modified: cfe/trunk/test/Analysis/plist-output.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/plist-output.m?rev=112789&r1=112788&r2=112789&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/plist-output.m (original)
+++ cfe/trunk/test/Analysis/plist-output.m Wed Sep  1 19:56:20 2010
@@ -205,7 +205,7 @@
 // CHECK:         </dict>
 // CHECK:         <dict>
 // CHECK:          <key>line</key><integer>10</integer>
-// CHECK:          <key>col</key><integer>3</integer>
+// CHECK:          <key>col</key><integer>7</integer>
 // CHECK:          <key>file</key><integer>0</integer>
 // CHECK:         </dict>
 // CHECK:        </array>





More information about the cfe-commits mailing list