summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2009-08-05 02:51:59 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2009-08-05 02:51:59 +0000
commitfe97165587089fd2872c78332619264d7a3125ff (patch)
treef8f797d731c2c78a9f1fc779589b8f6379c0871c
parent85f60cc5a83fa133dc7f8adad5e114a92b82b0b5 (diff)
downloadbcm5719-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.h4
-rw-r--r--clang/include/clang/Analysis/PathSensitive/ValueManager.h4
-rw-r--r--clang/lib/Analysis/GRExprEngine.cpp13
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)){
OpenPOWER on IntegriCloud