diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 8 | ||||
-rw-r--r-- | lib/Analysis/SVals.cpp | 17 | ||||
-rw-r--r-- | lib/Analysis/SymbolManager.cpp | 3 |
3 files changed, 26 insertions, 2 deletions
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; |