[cfe-commits] r112930 - in /cfe/trunk: include/clang/Checker/PathSensitive/Environment.h include/clang/Checker/PathSensitive/GRState.h lib/Checker/Environment.cpp lib/Checker/GRState.cpp

Ted Kremenek kremenek at apple.com
Thu Sep 2 18:07:02 PDT 2010


Author: kremenek
Date: Thu Sep  2 20:07:02 2010
New Revision: 112930

URL: http://llvm.org/viewvc/llvm-project?rev=112930&view=rev
Log:
Add optional record of "location" SVals in the environment.  When we analyzing loads/stores, we lose the location SVal, which makes it difficult to recover in some cases (e.g., for post diagnostics).  This is prep for pending changes to GRExprEngine.

Modified:
    cfe/trunk/include/clang/Checker/PathSensitive/Environment.h
    cfe/trunk/include/clang/Checker/PathSensitive/GRState.h
    cfe/trunk/lib/Checker/Environment.cpp
    cfe/trunk/lib/Checker/GRState.cpp

Modified: cfe/trunk/include/clang/Checker/PathSensitive/Environment.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Checker/PathSensitive/Environment.h?rev=112930&r1=112929&r2=112930&view=diff
==============================================================================
--- cfe/trunk/include/clang/Checker/PathSensitive/Environment.h (original)
+++ cfe/trunk/include/clang/Checker/PathSensitive/Environment.h Thu Sep  2 20:07:02 2010
@@ -83,8 +83,14 @@
     return Environment(F.GetEmptyMap());
   }
 
-  Environment BindExpr(Environment Env, const Stmt *S, SVal V,
+  /// Bind the value 'V' to the statement 'S'.
+  Environment bindExpr(Environment Env, const Stmt *S, SVal V,
                        bool Invalidate);
+  
+  /// Bind the location 'location' and value 'V' to the statement 'S'.  This
+  /// is used when simulating loads/stores.
+  Environment bindExprAndLocation(Environment Env, const Stmt *S, SVal location,
+                                  SVal V);
 
   Environment RemoveDeadBindings(Environment Env,
                                  SymbolReaper &SymReaper, const GRState *ST,

Modified: cfe/trunk/include/clang/Checker/PathSensitive/GRState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Checker/PathSensitive/GRState.h?rev=112930&r1=112929&r2=112930&view=diff
==============================================================================
--- cfe/trunk/include/clang/Checker/PathSensitive/GRState.h (original)
+++ cfe/trunk/include/clang/Checker/PathSensitive/GRState.h Thu Sep  2 20:07:02 2010
@@ -201,8 +201,15 @@
                                      const LocationContext *LC,
                                      SVal V) const;
 
+  /// Create a new state by binding the value 'V' to the statement 'S' in the
+  /// state's environment.
   const GRState *BindExpr(const Stmt *S, SVal V, bool Invalidate = true) const;
 
+  /// Create a new state by binding the value 'V' and location 'locaton' to the
+  /// statement 'S' in the state's environment.
+  const GRState *bindExprAndLocation(const Stmt *S, SVal location, SVal V)
+    const;
+  
   const GRState *bindDecl(const VarRegion *VR, SVal V) const;
 
   const GRState *bindDeclWithNoInit(const VarRegion *VR) const;

Modified: cfe/trunk/lib/Checker/Environment.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/Environment.cpp?rev=112930&r1=112929&r2=112930&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/Environment.cpp (original)
+++ cfe/trunk/lib/Checker/Environment.cpp Thu Sep  2 20:07:02 2010
@@ -80,7 +80,7 @@
   return LookupExpr(E);
 }
 
-Environment EnvironmentManager::BindExpr(Environment Env, const Stmt *S,
+Environment EnvironmentManager::bindExpr(Environment Env, const Stmt *S,
                                          SVal V, bool Invalidate) {
   assert(S);
 
@@ -94,6 +94,16 @@
   return Environment(F.Add(Env.ExprBindings, S, V));
 }
 
+static inline const Stmt *MakeLocation(const Stmt *S) {
+  return (const Stmt*) (((uintptr_t) S) | 0x1);
+}
+
+Environment EnvironmentManager::bindExprAndLocation(Environment Env,
+                                                    const Stmt *S,
+                                                    SVal location, SVal V) {
+  return Environment(F.Add(F.Add(Env.ExprBindings, MakeLocation(S), V), S, V));
+}
+
 namespace {
 class MarkLiveCallback : public SymbolVisitor {
   SymbolReaper &SymReaper;
@@ -115,6 +125,12 @@
   return false;
 }
 
+// In addition to mapping from Stmt * - > SVals in the Environment, we also
+// maintain a mapping from Stmt * -> SVals (locations) that were used during
+// a load and store.
+static inline bool IsLocation(const Stmt *S) {
+  return (bool) (((uintptr_t) S) & 0x1);
+}
 
 // RemoveDeadBindings:
 //  - Remove subexpression bindings.
@@ -123,7 +139,6 @@
 //   - Mark their reachable symbols live in SymbolReaper,
 //     see ScanReachableSymbols.
 //   - Mark the region in DRoots if the binding is a loc::MemRegionVal.
-
 Environment
 EnvironmentManager::RemoveDeadBindings(Environment Env,
                                        SymbolReaper &SymReaper,
@@ -136,12 +151,25 @@
   // individually removing all the subexpression bindings (which will greatly
   // outnumber block-level expression bindings).
   Environment NewEnv = getInitialEnvironment();
+  
+  llvm::SmallVector<std::pair<const Stmt*, SVal>, 10> deferredLocations;
 
   // Iterate over the block-expr bindings.
   for (Environment::iterator I = Env.begin(), E = Env.end();
        I != E; ++I) {
 
     const Stmt *BlkExpr = I.getKey();
+    
+    // For recorded locations (used when evaluating loads and stores), we
+    // consider them live only when their associated normal expression is
+    // also live.
+    // NOTE: This assumes that loads/stores that evaluated to UnknownVal
+    // still have an entry in the map.
+    if (IsLocation(BlkExpr)) {
+      deferredLocations.push_back(std::make_pair(BlkExpr, I.getData()));
+      continue;
+    }
+    
     const SVal &X = I.getData();
 
     // Block-level expressions in callers are assumed always live.
@@ -186,6 +214,15 @@
     if (X.isUndef() && cast<UndefinedVal>(X).getData())
       NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, BlkExpr, X);
   }
+  
+  // Go through he deferred locations and add them to the new environment if
+  // the correspond Stmt* is in the map as well.
+  for (llvm::SmallVectorImpl<std::pair<const Stmt*, SVal> >::iterator
+      I = deferredLocations.begin(), E = deferredLocations.end(); I != E; ++I) {
+    const Stmt *S = (Stmt*) (((uintptr_t) I->first) & (uintptr_t) ~0x1);
+    if (NewEnv.ExprBindings.lookup(S))
+      NewEnv.ExprBindings = F.Add(NewEnv.ExprBindings, I->first, I->second);
+  }
 
   return NewEnv;
 }

Modified: cfe/trunk/lib/Checker/GRState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/GRState.cpp?rev=112930&r1=112929&r2=112930&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/GRState.cpp (original)
+++ cfe/trunk/lib/Checker/GRState.cpp Thu Sep  2 20:07:02 2010
@@ -206,8 +206,8 @@
   return V;
 }
 
-const GRState *GRState::BindExpr(const Stmt* Ex, SVal V, bool Invalidate) const{
-  Environment NewEnv = getStateManager().EnvMgr.BindExpr(Env, Ex, V,
+const GRState *GRState::BindExpr(const Stmt* S, SVal V, bool Invalidate) const{
+  Environment NewEnv = getStateManager().EnvMgr.bindExpr(Env, S, V,
                                                          Invalidate);
   if (NewEnv == Env)
     return this;
@@ -217,6 +217,19 @@
   return getStateManager().getPersistentState(NewSt);
 }
 
+const GRState *GRState::bindExprAndLocation(const Stmt *S, SVal location,
+                                            SVal V) const {
+  Environment NewEnv =
+    getStateManager().EnvMgr.bindExprAndLocation(Env, S, location, V);
+
+  if (NewEnv == Env)
+    return this;
+  
+  GRState NewSt = *this;
+  NewSt.Env = NewEnv;
+  return getStateManager().getPersistentState(NewSt);
+}
+
 const GRState *GRState::AssumeInBound(DefinedOrUnknownSVal Idx,
                                       DefinedOrUnknownSVal UpperBound,
                                       bool Assumption) const {
@@ -295,6 +308,11 @@
 //  State pretty-printing.
 //===----------------------------------------------------------------------===//
 
+static bool IsEnvLoc(const Stmt *S) {
+  // FIXME: This is a layering violation.  Should be in environment.
+  return (bool) (((uintptr_t) S) & 0x1);
+}
+
 void GRState::print(llvm::raw_ostream& Out, CFG &C, const char* nl,
                     const char* sep) const {
   // Print the store.
@@ -304,8 +322,9 @@
   // Print Subexpression bindings.
   bool isFirst = true;
 
+  // FIXME: All environment printing should be moved inside Environment.
   for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) {
-    if (C.isBlkExpr(I.getKey()))
+    if (C.isBlkExpr(I.getKey()) || IsEnvLoc(I.getKey()))
       continue;
 
     if (isFirst) {
@@ -338,6 +357,27 @@
     I.getKey()->printPretty(Out, 0, PrintingPolicy(LO));
     Out << " : " << I.getData();
   }
+  
+  // Print locations.
+  isFirst = true;
+  
+  for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) {
+    if (!IsEnvLoc(I.getKey()))
+      continue;
+    
+    if (isFirst) {
+      Out << nl << nl << "Load/store locations:" << nl;
+      isFirst = false;
+    }
+    else { Out << nl; }
+
+    const Stmt *S = (Stmt*) (((uintptr_t) I.getKey()) & ((uintptr_t) ~0x1));
+    
+    Out << " (" << (void*) S << ") ";
+    LangOptions LO; // FIXME.
+    S->printPretty(Out, 0, PrintingPolicy(LO));
+    Out << " : " << I.getData();
+  }
 
   Mgr.getConstraintManager().print(this, Out, nl, sep);
 





More information about the cfe-commits mailing list