]> granicus.if.org Git - clang/commitdiff
Add GRState::getSimplifiedSVal(), which provides an API hook for doing symbol ->...
authorTed Kremenek <kremenek@apple.com>
Fri, 3 Sep 2010 01:06:58 +0000 (01:06 +0000)
committerTed Kremenek <kremenek@apple.com>
Fri, 3 Sep 2010 01:06:58 +0000 (01:06 +0000)
is prep for some pending optimizations in GRExprEngine.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112929 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Checker/PathSensitive/GRState.h
lib/Checker/GRState.cpp

index 984118ea2fa284e240da1612625a70f632a3ceee..7d998905de411659d5db92fd07ee77a3f12a5f43 100644 (file)
@@ -257,11 +257,18 @@ public:
 
   const llvm::APSInt *getSymVal(SymbolRef sym) const;
 
-  SVal getSVal(const Stmt* Ex) const;
-
+  /// Returns the SVal bound to the statement 'S' in the state's environment.
+  SVal getSVal(const Stmt* S) const;
+  
   SVal getSValAsScalarOrLoc(const Stmt *Ex) const;
 
   SVal getSVal(Loc LV, QualType T = QualType()) const;
+  
+  /// Returns a "simplified" SVal bound to the location 'LV' in the state's
+  /// store.  A simplified SVal will include optimizations such as
+  /// if the SVal is a symbol whose value is perfectly constrained then that
+  /// constant value is returned instead.
+  SVal getSimplifiedSVal(Loc LV, QualType T= QualType()) const;
 
   SVal getSVal(const MemRegion* R) const;
 
index 024237c8cbe6fae48a2953754801a4eee1ef0bfd..2a7c6dc66e72d30bd7ffd18e3ede796bca212414 100644 (file)
@@ -169,6 +169,42 @@ SVal GRState::getSValAsScalarOrLoc(const MemRegion *R) const {
   return UnknownVal();
 }
 
+SVal GRState::getSimplifiedSVal(Loc location, QualType T) const {
+  SVal V = getSVal(cast<Loc>(location), T);
+  
+  // If 'V' is a symbolic value that is *perfectly* constrained to
+  // be a constant value, use that value instead to lessen the burden
+  // on later analysis stages (so we have less symbolic values to reason
+  // about).
+  if (!T.isNull()) {
+    if (SymbolRef sym = V.getAsSymbol()) {
+      if (const llvm::APSInt *Int = getSymVal(sym)) {
+        // FIXME: Because we don't correctly model (yet) sign-extension
+        // and truncation of symbolic values, we need to convert
+        // the integer value to the correct signedness and bitwidth.
+        //
+        // This shows up in the following:
+        //
+        //   char foo();
+        //   unsigned x = foo();
+        //   if (x == 54)
+        //     ...
+        //
+        //  The symbolic value stored to 'x' is actually the conjured
+        //  symbol for the call to foo(); the type of that symbol is 'char',
+        //  not unsigned.
+        const llvm::APSInt &NewV = getBasicVals().Convert(T, *Int);
+        
+        if (isa<Loc>(V))
+          return loc::ConcreteInt(NewV);
+        else
+          return nonloc::ConcreteInt(NewV);
+      }
+    }
+  }
+  
+  return V;
+}
 
 const GRState *GRState::BindExpr(const Stmt* Ex, SVal V, bool Invalidate) const{
   Environment NewEnv = getStateManager().EnvMgr.BindExpr(Env, Ex, V,