]> granicus.if.org Git - clang/commitdiff
If the UnaryOperator has non-location type, use its type to create the
authorZhongxing Xu <xuzhongxing@gmail.com>
Wed, 5 Aug 2009 02:51:59 +0000 (02:51 +0000)
committerZhongxing Xu <xuzhongxing@gmail.com>
Wed, 5 Aug 2009 02:51:59 +0000 (02:51 +0000)
constant value. If the UnaryOperator has location type, create the
constant with int type and pointer width.

This fixes the bug that all pointer increments 'p++' evaluated to Unknown.

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

include/clang/Analysis/PathSensitive/BasicValueFactory.h
include/clang/Analysis/PathSensitive/ValueManager.h
lib/Analysis/GRExprEngine.cpp

index b694e9b299408df25f23b6befd8d1f67e31006e2..71a705d2d7e6f0d238ec4c09fc275632c7cbe469 100644 (file)
@@ -126,6 +126,10 @@ public:
     return getValue(0, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned);
   }
 
+  inline const llvm::APSInt &getIntWithPtrWidth(uint64_t X, bool isUnsigned) {
+    return getValue(X, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned);
+  }
+
   inline const llvm::APSInt& getTruthValue(bool b, QualType T) {
     return getValue(b ? 1 : 0, Ctx.getTypeSize(T), false);
   }
index 711ac4a8bc500b15360e1778cae151ceed52f870..cc4fe9fc63ed924f08d5c314e5b738d6817affaf 100644 (file)
@@ -152,6 +152,10 @@ public:
     return nonloc::ConcreteInt(BasicVals.getIntValue(X, isUnsigned));
   }
 
+  NonLoc makeIntValWithPtrWidth(uint64_t X, bool isUnsigned) {
+    return nonloc::ConcreteInt(BasicVals.getIntWithPtrWidth(X, isUnsigned));
+  }
+
   NonLoc makeIntVal(uint64_t X, unsigned BitWidth, bool isUnsigned) {
     return nonloc::ConcreteInt(BasicVals.getValue(X, BitWidth, isUnsigned));
   }
index 14333875f8b44015fdf629a03d79801a0732ae2d..2f511708956b66e43a15b28037bcd4fb3c583e89 100644 (file)
@@ -2568,8 +2568,17 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred,
       BinaryOperator::Opcode Op = U->isIncrementOp() ? BinaryOperator::Add
                                                      : BinaryOperator::Sub;
 
-      SVal Result = EvalBinOp(state, Op, V2, ValMgr.makeIntVal(1U,U->getType()),
-                              U->getType());    
+      // If the UnaryOperator has non-location type, use its type to create the
+      // constant value. If the UnaryOperator has location type, create the
+      // constant with int type and pointer width.
+      SVal RHS;
+
+      if (U->getType()->isAnyPointerType())
+        RHS = ValMgr.makeIntValWithPtrWidth(1, false);
+      else
+        RHS = ValMgr.makeIntVal(1, U->getType());
+
+      SVal Result = EvalBinOp(state, Op, V2, RHS, U->getType());    
       
       // Conjure a new symbol if necessary to recover precision.
       if (Result.isUnknown() || !getConstraintManager().canReasonAbout(Result)){