From bb9b2711ded08d39f9c9aa08b06ac5e288f32c62 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 20 Mar 2009 20:10:45 +0000 Subject: [PATCH] GRExprEngine: - Conjure symbols at '--' and '++' unary operations - Add utility method SVal::GetConjuredSymbolVal() and constify some arguments along the way. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67395 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Analysis/PathSensitive/SVals.h | 3 +++ .../Analysis/PathSensitive/SymbolManager.h | 14 +++++++------- lib/Analysis/GRExprEngine.cpp | 8 +++++++- lib/Analysis/SVals.cpp | 17 +++++++++++++++++ lib/Analysis/SymbolManager.cpp | 3 ++- 5 files changed, 36 insertions(+), 9 deletions(-) diff --git a/include/clang/Analysis/PathSensitive/SVals.h b/include/clang/Analysis/PathSensitive/SVals.h index 42cd4225d3..bb797f4884 100644 --- a/include/clang/Analysis/PathSensitive/SVals.h +++ b/include/clang/Analysis/PathSensitive/SVals.h @@ -74,6 +74,9 @@ public: /// GetRValueSymbolVal - make a unique symbol for value of R. static SVal GetRValueSymbolVal(SymbolManager& SymMgr, const MemRegion* R); + static SVal GetConjuredSymbolVal(SymbolManager& SymMgr, const Expr *E, + unsigned Count); + inline bool isUnknown() const { return getRawKind() == UnknownKind; } diff --git a/include/clang/Analysis/PathSensitive/SymbolManager.h b/include/clang/Analysis/PathSensitive/SymbolManager.h index 5096402229..dfc1ae81ee 100644 --- a/include/clang/Analysis/PathSensitive/SymbolManager.h +++ b/include/clang/Analysis/PathSensitive/SymbolManager.h @@ -135,25 +135,25 @@ public: }; class SymbolConjured : public SymbolData { - Stmt* S; + const Stmt* S; QualType T; unsigned Count; const void* SymbolTag; public: - SymbolConjured(SymbolRef Sym, Stmt* s, QualType t, unsigned count, + SymbolConjured(SymbolRef Sym, const Stmt* s, QualType t, unsigned count, const void* symbolTag) : SymbolData(ConjuredKind, Sym), S(s), T(t), Count(count), SymbolTag(symbolTag) {} - Stmt* getStmt() const { return S; } + const Stmt* getStmt() const { return S; } unsigned getCount() const { return Count; } const void* getTag() const { return SymbolTag; } QualType getType(ASTContext&) const; - static void Profile(llvm::FoldingSetNodeID& profile, Stmt* S, QualType T, - unsigned Count, const void* SymbolTag) { + static void Profile(llvm::FoldingSetNodeID& profile, const Stmt* S, + QualType T, unsigned Count, const void* SymbolTag) { profile.AddInteger((unsigned) ConjuredKind); profile.AddPointer(S); profile.Add(T); @@ -221,10 +221,10 @@ public: /// Make a unique symbol for MemRegion R according to its kind. SymbolRef getRegionRValueSymbol(const MemRegion* R); - SymbolRef getConjuredSymbol(Stmt* E, QualType T, unsigned VisitCount, + SymbolRef getConjuredSymbol(const Stmt* E, QualType T, unsigned VisitCount, const void* SymbolTag = 0); - SymbolRef getConjuredSymbol(Expr* E, unsigned VisitCount, + SymbolRef getConjuredSymbol(const Expr* E, unsigned VisitCount, const void* SymbolTag = 0) { return getConjuredSymbol(E, E->getType(), VisitCount, SymbolTag); } diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 1f47bc7f33..80467ebb27 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -2449,7 +2449,13 @@ void GRExprEngine::VisitUnaryOperator(UnaryOperator* U, NodeTy* Pred, BinaryOperator::Opcode Op = U->isIncrementOp() ? BinaryOperator::Add : BinaryOperator::Sub; - SVal Result = EvalBinOp(Op, V2, MakeConstantVal(1U, U)); + SVal Result = EvalBinOp(Op, V2, MakeConstantVal(1U, U)); + + // Conjure a new symbol if necessary to recover precision. + if (Result.isUnknown() || !getConstraintManager().canReasonAbout(Result)) + Result = SVal::GetConjuredSymbolVal(SymMgr, Ex, + Builder->getCurrentBlockCount()); + state = BindExpr(state, U, U->isPostfix() ? V2 : Result); // Perform the store. diff --git a/lib/Analysis/SVals.cpp b/lib/Analysis/SVals.cpp index 3762ae5ce6..12bf795972 100644 --- a/lib/Analysis/SVals.cpp +++ b/lib/Analysis/SVals.cpp @@ -338,6 +338,23 @@ SVal SVal::GetRValueSymbolVal(SymbolManager& SymMgr, const MemRegion* R) { return UnknownVal(); } +SVal SVal::GetConjuredSymbolVal(SymbolManager &SymMgr, const Expr* E, + unsigned Count) { + + QualType T = E->getType(); + + if (Loc::IsLocType(T)) { + SymbolRef Sym = SymMgr.getConjuredSymbol(E, Count); + return loc::SymbolVal(Sym); + } + else if (T->isIntegerType() && T->isScalarType()) { + SymbolRef Sym = SymMgr.getConjuredSymbol(E, Count); + return nonloc::SymbolVal(Sym); + } + + return UnknownVal(); +} + nonloc::LocAsInteger nonloc::LocAsInteger::Make(BasicValueFactory& Vals, Loc V, unsigned Bits) { return LocAsInteger(Vals.getPersistentSValWithData(V, Bits)); diff --git a/lib/Analysis/SymbolManager.cpp b/lib/Analysis/SymbolManager.cpp index 589178fecb..4d101f186b 100644 --- a/lib/Analysis/SymbolManager.cpp +++ b/lib/Analysis/SymbolManager.cpp @@ -52,7 +52,8 @@ SymbolRef SymbolManager::getRegionRValueSymbol(const MemRegion* R) { return SymbolCounter++; } -SymbolRef SymbolManager::getConjuredSymbol(Stmt* E, QualType T, unsigned Count, +SymbolRef SymbolManager::getConjuredSymbol(const Stmt* E, QualType T, + unsigned Count, const void* SymbolTag) { llvm::FoldingSetNodeID profile; -- 2.40.0