[cfe-commits] r82737 - in /cfe/trunk: include/clang/Analysis/PathSensitive/BasicValueFactory.h lib/Analysis/SimpleConstraintManager.cpp lib/Analysis/SimpleSValuator.cpp test/Analysis/misc-ps-region-store.m

Ted Kremenek kremenek at apple.com
Thu Sep 24 17:18:15 PDT 2009


Author: kremenek
Date: Thu Sep 24 19:18:15 2009
New Revision: 82737

URL: http://llvm.org/viewvc/llvm-project?rev=82737&view=rev
Log:
Fix <rdar://problem/7249327> by allowing silent conversions between signed and unsigned integer values for symbolic values.  This is an intermediate solution (i.e. hack) until we support extension/truncation of symbolic integers.

Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/BasicValueFactory.h
    cfe/trunk/lib/Analysis/SimpleConstraintManager.cpp
    cfe/trunk/lib/Analysis/SimpleSValuator.cpp
    cfe/trunk/test/Analysis/misc-ps-region-store.m

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

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/BasicValueFactory.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/BasicValueFactory.h Thu Sep 24 19:18:15 2009
@@ -92,16 +92,25 @@
 
   /// Convert - Create a new persistent APSInt with the same value as 'From'
   ///  but with the bitwidth and signedness of 'To'.
-  const llvm::APSInt& Convert(const llvm::APSInt& To,
+  const llvm::APSInt &Convert(const llvm::APSInt& To,
                               const llvm::APSInt& From) {
 
     if (To.isUnsigned() == From.isUnsigned() &&
         To.getBitWidth() == From.getBitWidth())
       return From;
 
-    return getValue(From.getSExtValue(),
-                    To.getBitWidth(),
-                    To.isUnsigned());
+    return getValue(From.getSExtValue(), To.getBitWidth(), To.isUnsigned());
+  }
+  
+  const llvm::APSInt &Convert(QualType T, const llvm::APSInt &From) {
+    assert(T->isIntegerType() || Loc::IsLocType(T));
+    unsigned bitwidth = Ctx.getTypeSize(T);
+    bool isUnsigned = T->isUnsignedIntegerType() || Loc::IsLocType(T);
+    
+    if (isUnsigned == From.isUnsigned() && bitwidth == From.getBitWidth())
+      return From;
+    
+    return getValue(From.getSExtValue(), bitwidth, isUnsigned);
   }
 
   const llvm::APSInt& getIntValue(uint64_t X, bool isUnsigned) {

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

==============================================================================
--- cfe/trunk/lib/Analysis/SimpleConstraintManager.cpp (original)
+++ cfe/trunk/lib/Analysis/SimpleConstraintManager.cpp Thu Sep 24 19:18:15 2009
@@ -162,8 +162,19 @@
 
   case nonloc::SymExprValKind: {
     nonloc::SymExprVal V = cast<nonloc::SymExprVal>(Cond);
-    if (const SymIntExpr *SE = dyn_cast<SymIntExpr>(V.getSymbolicExpression()))
-      return AssumeSymInt(state, Assumption, SE);
+    if (const SymIntExpr *SE = dyn_cast<SymIntExpr>(V.getSymbolicExpression())){
+      // FIXME: This is a hack.  It silently converts the RHS integer to be
+      // of the same type as on the left side.  This should be removed once
+      // we support truncation/extension of symbolic values.      
+      GRStateManager &StateMgr = state->getStateManager();
+      ASTContext &Ctx = StateMgr.getContext();
+      QualType LHSType = SE->getLHS()->getType(Ctx);
+      BasicValueFactory &BasicVals = StateMgr.getBasicVals();
+      const llvm::APSInt &RHS = BasicVals.Convert(LHSType, SE->getRHS());
+      SymIntExpr SENew(SE->getLHS(), SE->getOpcode(), RHS, SE->getType(Ctx));
+
+      return AssumeSymInt(state, Assumption, &SENew);
+    }
 
     // For all other symbolic expressions, over-approximate and consider
     // the constraint feasible.

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

==============================================================================
--- cfe/trunk/lib/Analysis/SimpleSValuator.cpp (original)
+++ cfe/trunk/lib/Analysis/SimpleSValuator.cpp Thu Sep 24 19:18:15 2009
@@ -68,6 +68,15 @@
     QualType T = Ctx.getCanonicalType(se->getType(Ctx));
     if (T == Ctx.getCanonicalType(castTy))
       return val;
+    
+    // FIXME: Remove this hack when we support symbolic truncation/extension.
+    // HACK: If both castTy and T are integers, ignore the cast.  This is
+    // not a permanent solution.  Eventually we want to precisely handle
+    // extension/truncation of symbolic integers.  This prevents us from losing
+    // precision when we assign 'x = y' and 'y' is symbolic and x and y are
+    // different integer types.
+    if (T->isIntegerType() && castTy->isIntegerType())
+      return val;
 
     return UnknownVal();
   }

Modified: cfe/trunk/test/Analysis/misc-ps-region-store.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/misc-ps-region-store.m?rev=82737&r1=82736&r2=82737&view=diff

==============================================================================
--- cfe/trunk/test/Analysis/misc-ps-region-store.m (original)
+++ cfe/trunk/test/Analysis/misc-ps-region-store.m Thu Sep 24 19:18:15 2009
@@ -207,3 +207,33 @@
   *p = 0xDEADBEEF; // no-warning
 }
 
+// <rdar://problem/7249327> - This test case tests both value tracking of
+// array values and that we handle symbolic values that are casted
+// between different integer types.  Note the assignment 'n = *a++'; here
+// 'n' is and 'int' and '*a' is 'unsigned'.  Previously we got a false positive
+// at 'x += *b++' (undefined value) because we got a false path.
+int rdar_7249327_aux(void);
+
+void rdar_7249327(unsigned int A[2*32]) {
+  int B[2*32];
+  int *b;
+  unsigned int *a;
+  int x = 0;
+  
+  int n;
+  
+  a = A;
+  b = B;
+  
+  n = *a++;
+  if (n)
+    *b++ = rdar_7249327_aux();
+
+  a = A;
+  b = B;
+  
+  n = *a++;
+  if (n)
+    x += *b++; // no-warning
+}
+





More information about the cfe-commits mailing list