diff options
author | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-08-05 02:51:59 +0000 |
---|---|---|
committer | Zhongxing Xu <xuzhongxing@gmail.com> | 2009-08-05 02:51:59 +0000 |
commit | fe97165587089fd2872c78332619264d7a3125ff (patch) | |
tree | f8f797d731c2c78a9f1fc779589b8f6379c0871c | |
parent | 85f60cc5a83fa133dc7f8adad5e114a92b82b0b5 (diff) | |
download | bcm5719-llvm-fe97165587089fd2872c78332619264d7a3125ff.tar.gz bcm5719-llvm-fe97165587089fd2872c78332619264d7a3125ff.zip |
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.
This fixes the bug that all pointer increments 'p++' evaluated to Unknown.
llvm-svn: 78147
-rw-r--r-- | clang/include/clang/Analysis/PathSensitive/BasicValueFactory.h | 4 | ||||
-rw-r--r-- | clang/include/clang/Analysis/PathSensitive/ValueManager.h | 4 | ||||
-rw-r--r-- | clang/lib/Analysis/GRExprEngine.cpp | 13 |
3 files changed, 19 insertions, 2 deletions
diff --git a/clang/include/clang/Analysis/PathSensitive/BasicValueFactory.h b/clang/include/clang/Analysis/PathSensitive/BasicValueFactory.h index b694e9b2994..71a705d2d7e 100644 --- a/clang/include/clang/Analysis/PathSensitive/BasicValueFactory.h +++ b/clang/include/clang/Analysis/PathSensitive/BasicValueFactory.h @@ -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); } diff --git a/clang/include/clang/Analysis/PathSensitive/ValueManager.h b/clang/include/clang/Analysis/PathSensitive/ValueManager.h index 711ac4a8bc5..cc4fe9fc63e 100644 --- a/clang/include/clang/Analysis/PathSensitive/ValueManager.h +++ b/clang/include/clang/Analysis/PathSensitive/ValueManager.h @@ -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)); } diff --git a/clang/lib/Analysis/GRExprEngine.cpp b/clang/lib/Analysis/GRExprEngine.cpp index 14333875f8b..2f511708956 100644 --- a/clang/lib/Analysis/GRExprEngine.cpp +++ b/clang/lib/Analysis/GRExprEngine.cpp @@ -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)){ |