[cfe-commits] r86084 - in /cfe/trunk: include/clang/Analysis/PathSensitive/Checker.h include/clang/Analysis/PathSensitive/Checkers/UndefinedAssignmentChecker.h include/clang/Analysis/PathSensitive/GRExprEngine.h lib/Analysis/GRExprEngine.cpp lib/Analysis/UndefinedAssignmentChecker.cpp

Ted Kremenek kremenek at apple.com
Wed Nov 4 16:42:23 PST 2009


Author: kremenek
Date: Wed Nov  4 18:42:23 2009
New Revision: 86084

URL: http://llvm.org/viewvc/llvm-project?rev=86084&view=rev
Log:
Modify GRExprEngine::EvalBind() to take both a "store expression" and
an "assign expression", representing the expressions where the value
binding occurs and the assignment takes place respectively.  These are
largely syntactic clues for better error reporting.

Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/Checker.h
    cfe/trunk/include/clang/Analysis/PathSensitive/Checkers/UndefinedAssignmentChecker.h
    cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
    cfe/trunk/lib/Analysis/GRExprEngine.cpp
    cfe/trunk/lib/Analysis/UndefinedAssignmentChecker.cpp

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=86084&r1=86083&r2=86084&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/Checker.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/Checker.h Wed Nov  4 18:42:23 2009
@@ -116,12 +116,13 @@
 
   void GR_VisitBind(ExplodedNodeSet &Dst,
                     GRStmtNodeBuilder &Builder, GRExprEngine &Eng,
-                    const Stmt *stmt, ExplodedNode *Pred, void *tag, 
+                    const Stmt *AssignE,
+                    const Stmt *StoreE, ExplodedNode *Pred, void *tag, 
                     SVal location, SVal val,
                     bool isPrevisit) {
     CheckerContext C(Dst, Builder, Eng, Pred, tag, isPrevisit);
     assert(isPrevisit && "Only previsit supported for now.");
-    PreVisitBind(C, stmt, location, val);
+    PreVisitBind(C, AssignE, StoreE, location, val);
   }
 
 public:
@@ -135,7 +136,8 @@
     return Pred;
   }
   
-  virtual void PreVisitBind(CheckerContext &C, const Stmt *ST, 
+  virtual void PreVisitBind(CheckerContext &C,
+                            const Stmt *AssignE, const Stmt *StoreE, 
                             SVal location, SVal val) {}
 
   virtual ExplodedNode *CheckType(QualType T, ExplodedNode *Pred, 

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/Checkers/UndefinedAssignmentChecker.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/Checkers/UndefinedAssignmentChecker.h?rev=86084&r1=86083&r2=86084&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/Checkers/UndefinedAssignmentChecker.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/Checkers/UndefinedAssignmentChecker.h Wed Nov  4 18:42:23 2009
@@ -24,7 +24,8 @@
 public:
   UndefinedAssignmentChecker() : BT(0) {}
   static void *getTag();
-  virtual void PreVisitBind(CheckerContext &C, const Stmt *S, SVal location,
+  virtual void PreVisitBind(CheckerContext &C, const Stmt *AssignE,
+                            const Stmt *StoreE, SVal location,
                             SVal val);
 };
 }

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

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Wed Nov  4 18:42:23 2009
@@ -412,7 +412,8 @@
   void CheckerVisit(Stmt *S, ExplodedNodeSet &Dst, ExplodedNodeSet &Src, 
                     bool isPrevisit);
   
-  void CheckerVisitBind(Stmt *S, ExplodedNodeSet &Dst, ExplodedNodeSet &Src, 
+  void CheckerVisitBind(const Stmt *AssignE, const Stmt *StoreE,
+                        ExplodedNodeSet &Dst, ExplodedNodeSet &Src, 
                         SVal location, SVal val, bool isPrevisit);
 
 
@@ -566,7 +567,8 @@
 
   /// 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, Stmt* Ex, ExplodedNode* Pred,
+  void EvalBind(ExplodedNodeSet& Dst, Stmt *AssignE,
+                Stmt* StoreE, ExplodedNode* Pred,
                 const GRState* St, SVal location, SVal Val,
                 bool atDeclInit = false);
 
@@ -578,14 +580,10 @@
                        const GRState* St, SVal location,
                        const void *tag = 0);
 
-
-  void EvalStore(ExplodedNodeSet& Dst, Expr* E, ExplodedNode* Pred, const GRState* St,
-                 SVal TargetLV, SVal Val, const void *tag = 0);
-
-  void EvalStore(ExplodedNodeSet& Dst, Expr* E, Expr* StoreE, ExplodedNode* Pred,
+  void EvalStore(ExplodedNodeSet& Dst, Expr* AssignE, Expr* StoreE,
+                 ExplodedNode* Pred,
                  const GRState* St, SVal TargetLV, SVal Val,
                  const void *tag = 0);
-
 };
 
 } // end clang namespace

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

==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Wed Nov  4 18:42:23 2009
@@ -141,7 +141,8 @@
 
 // FIXME: This is largely copy-paste from CheckerVisit().  Need to 
 // unify.
-void GRExprEngine::CheckerVisitBind(Stmt *S, ExplodedNodeSet &Dst,
+void GRExprEngine::CheckerVisitBind(const Stmt *AssignE, const Stmt *StoreE,
+                                    ExplodedNodeSet &Dst,
                                     ExplodedNodeSet &Src,
                                     SVal location, SVal val, bool isPrevisit) {
   
@@ -164,8 +165,8 @@
     
     for (ExplodedNodeSet::iterator NI = PrevSet->begin(), NE = PrevSet->end();
          NI != NE; ++NI)
-      checker->GR_VisitBind(*CurrSet, *Builder, *this, S, *NI, tag, location,
-                            val, isPrevisit);
+      checker->GR_VisitBind(*CurrSet, *Builder, *this, AssignE, StoreE,
+                            *NI, tag, location, val, isPrevisit);
     
     // Update which NodeSet is the current one.
     PrevSet = CurrSet;
@@ -1125,7 +1126,8 @@
 
 /// 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, Stmt* Ex, ExplodedNode* Pred,
+void GRExprEngine::EvalBind(ExplodedNodeSet& Dst, Stmt *AssignE,
+                            Stmt* StoreE, ExplodedNode* Pred,
                             const GRState* state, SVal location, SVal Val,
                             bool atDeclInit) {
   
@@ -1133,7 +1135,7 @@
   // Do a previsit of the bind.
   ExplodedNodeSet CheckedSet, Src;
   Src.Add(Pred);
-  CheckerVisitBind(Ex, CheckedSet, Src, location, Val, true);
+  CheckerVisitBind(AssignE, StoreE, CheckedSet, Src, location, Val, true);
   
   for (ExplodedNodeSet::iterator I = CheckedSet.begin(), E = CheckedSet.end();
        I!=E; ++I) {
@@ -1166,7 +1168,7 @@
     // 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.
-    GRStmtNodeBuilderRef BuilderRef(Dst, *Builder, *this, *I, newState, Ex,
+    GRStmtNodeBuilderRef BuilderRef(Dst, *Builder, *this, *I, newState, StoreE,
                                     newState != state);
 
     getTF().EvalBind(BuilderRef, location, Val);
@@ -1179,14 +1181,16 @@
 ///  @param state The current simulation state
 ///  @param location The location to store the value
 ///  @param Val The value to be stored
-void GRExprEngine::EvalStore(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
+void GRExprEngine::EvalStore(ExplodedNodeSet& Dst, Expr *AssignE,
+                             Expr* StoreE,
+                             ExplodedNode* Pred,
                              const GRState* state, SVal location, SVal Val,
                              const void *tag) {
 
-  assert (Builder && "GRStmtNodeBuilder must be defined.");
+  assert(Builder && "GRStmtNodeBuilder must be defined.");
 
   // Evaluate the location (checks for bad dereferences).
-  Pred = EvalLocation(Ex, Pred, state, location, tag);
+  Pred = EvalLocation(StoreE, Pred, state, location, tag);
 
   if (!Pred)
     return;
@@ -1199,7 +1203,7 @@
   SaveAndRestore<const void*> OldTag(Builder->Tag);
   Builder->PointKind = ProgramPoint::PostStoreKind;
   Builder->Tag = tag;
-  EvalBind(Dst, Ex, Pred, state, location, Val);
+  EvalBind(Dst, AssignE, StoreE, Pred, state, location, Val);
 }
 
 void GRExprEngine::EvalLoad(ExplodedNodeSet& Dst, Expr* Ex, ExplodedNode* Pred,
@@ -1231,17 +1235,6 @@
   }
 }
 
-void GRExprEngine::EvalStore(ExplodedNodeSet& Dst, Expr* Ex, Expr* StoreE,
-                             ExplodedNode* Pred, const GRState* state,
-                             SVal location, SVal Val, const void *tag) {
-
-  ExplodedNodeSet TmpDst;
-  EvalStore(TmpDst, StoreE, Pred, state, location, Val, tag);
-
-  for (ExplodedNodeSet::iterator I=TmpDst.begin(), E=TmpDst.end(); I!=E; ++I)
-    MakeNode(Dst, Ex, *I, (*I)->getState(), ProgramPoint::PostStmtKind, tag);
-}
-
 ExplodedNode* GRExprEngine::EvalLocation(Stmt* Ex, ExplodedNode* Pred,
                                          const GRState* state, SVal location,
                                          const void *tag) {
@@ -1402,7 +1395,7 @@
                                                 newValueExpr->getType());
       }
 
-      Engine.EvalStore(TmpStore, theValueExpr, N, stateEqual, location,
+      Engine.EvalStore(TmpStore, NULL, theValueExpr, N, stateEqual, location,
                        val, OSAtomicStoreTag);
 
       // Now bind the result of the comparison.
@@ -2147,8 +2140,8 @@
                                                Builder->getCurrentBlockCount());
       }
       
-      EvalBind(Dst, DS, *I, state, loc::MemRegionVal(state->getRegion(VD, LC)),
-               InitVal, true);                                                     
+      EvalBind(Dst, DS, DS, *I, state,
+               loc::MemRegionVal(state->getRegion(VD, LC)), InitVal, true);                                                     
     }
     else {
       state = state->bindDeclWithNoInit(state->getRegion(VD, LC));
@@ -2570,7 +2563,7 @@
       state = state->BindExpr(U, U->isPostfix() ? V2 : Result);
 
       // Perform the store.
-      EvalStore(Dst, U, *I2, state, V1, Result);
+      EvalStore(Dst, NULL, U, *I2, state, V1, Result);
     }
   }
 }

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

==============================================================================
--- cfe/trunk/lib/Analysis/UndefinedAssignmentChecker.cpp (original)
+++ cfe/trunk/lib/Analysis/UndefinedAssignmentChecker.cpp Wed Nov  4 18:42:23 2009
@@ -22,14 +22,15 @@
   return &x;
 }
 
-void UndefinedAssignmentChecker::PreVisitBind(CheckerContext &C, 
-                                              const Stmt *S,
+void UndefinedAssignmentChecker::PreVisitBind(CheckerContext &C,
+                                              const Stmt *AssignE,
+                                              const Stmt *StoreE,
                                               SVal location,
                                               SVal val) {
   if (!val.isUndef())
     return;
 
-  ExplodedNode *N = C.GenerateNode(S, true);
+  ExplodedNode *N = C.GenerateNode(StoreE, true);
 
   if (!N)
     return;
@@ -40,20 +41,20 @@
 
   // Generate a report for this bug.
   EnhancedBugReport *R = new EnhancedBugReport(*BT, BT->getName().c_str(), N);
-  const Expr *ex = 0;
 
-  // FIXME: This check needs to be done on the expression doing the
-  // assignment, not the "store" expression.
-  if (const BinaryOperator *B = dyn_cast<BinaryOperator>(S))
-    ex = B->getRHS();
-  else if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
-    const VarDecl* VD = dyn_cast<VarDecl>(DS->getSingleDecl());
-    ex = VD->getInit();
-  }
+  if (AssignE) {
+    const Expr *ex = 0;
 
-  if (ex) {
-    R->addRange(ex->getSourceRange());
-    R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, ex);
+    if (const BinaryOperator *B = dyn_cast<BinaryOperator>(AssignE))
+      ex = B->getRHS();
+    else if (const DeclStmt *DS = dyn_cast<DeclStmt>(AssignE)) {
+      const VarDecl* VD = dyn_cast<VarDecl>(DS->getSingleDecl());
+      ex = VD->getInit();
+    }
+    if (ex) {
+      R->addRange(ex->getSourceRange());
+      R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, ex);
+    }
   }
 
   C.EmitReport(R);





More information about the cfe-commits mailing list