diff options
Diffstat (limited to 'lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp index beae0dfae2896..62c54fc956a96 100644 --- a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -440,7 +440,7 @@ static bool shouldRearrange(ProgramStateRef State, BinaryOperator::Opcode Op, SymbolRef Sym, llvm::APSInt Int, QualType Ty) { return Sym->getType() == Ty && (!BinaryOperator::isComparisonOp(Op) || - (isWithinConstantOverflowBounds(Sym, State) && + (isWithinConstantOverflowBounds(Sym, State) && isWithinConstantOverflowBounds(Int))); } @@ -1236,11 +1236,21 @@ SVal SimpleSValBuilder::simplifySVal(ProgramStateRef State, SVal V) { return Sym == Val.getAsSymbol(); } + SVal cache(SymbolRef Sym, SVal V) { + Cached[Sym] = V; + return V; + } + + SVal skip(SymbolRef Sym) { + return cache(Sym, SVB.makeSymbolVal(Sym)); + } + public: Simplifier(ProgramStateRef State) : State(State), SVB(State->getStateManager().getSValBuilder()) {} SVal VisitSymbolData(const SymbolData *S) { + // No cache here. if (const llvm::APSInt *I = SVB.getKnownValue(State, SVB.makeSymbolVal(S))) return Loc::isLocType(S->getType()) ? (SVal)SVB.makeIntLocVal(*I) @@ -1257,11 +1267,9 @@ SVal SimpleSValBuilder::simplifySVal(ProgramStateRef State, SVal V) { return I->second; SVal LHS = Visit(S->getLHS()); - if (isUnchanged(S->getLHS(), LHS)) { - SVal V = SVB.makeSymbolVal(S); - Cached[S] = V; - return V; - } + if (isUnchanged(S->getLHS(), LHS)) + return skip(S); + SVal RHS; // By looking at the APSInt in the right-hand side of S, we cannot // figure out if it should be treated as a Loc or as a NonLoc. @@ -1281,9 +1289,8 @@ SVal SimpleSValBuilder::simplifySVal(ProgramStateRef State, SVal V) { RHS = SVB.makeIntVal(S->getRHS()); } - SVal V = SVB.evalBinOp(State, S->getOpcode(), LHS, RHS, S->getType()); - Cached[S] = V; - return V; + return cache( + S, SVB.evalBinOp(State, S->getOpcode(), LHS, RHS, S->getType())); } SVal VisitSymSymExpr(const SymSymExpr *S) { @@ -1291,16 +1298,21 @@ SVal SimpleSValBuilder::simplifySVal(ProgramStateRef State, SVal V) { if (I != Cached.end()) return I->second; + // For now don't try to simplify mixed Loc/NonLoc expressions + // because they often appear from LocAsInteger operations + // and we don't know how to combine a LocAsInteger + // with a concrete value. + if (Loc::isLocType(S->getLHS()->getType()) != + Loc::isLocType(S->getRHS()->getType())) + return skip(S); + SVal LHS = Visit(S->getLHS()); SVal RHS = Visit(S->getRHS()); - if (isUnchanged(S->getLHS(), LHS) && isUnchanged(S->getRHS(), RHS)) { - SVal V = SVB.makeSymbolVal(S); - Cached[S] = V; - return V; - } - SVal V = SVB.evalBinOp(State, S->getOpcode(), LHS, RHS, S->getType()); - Cached[S] = V; - return V; + if (isUnchanged(S->getLHS(), LHS) && isUnchanged(S->getRHS(), RHS)) + return skip(S); + + return cache( + S, SVB.evalBinOp(State, S->getOpcode(), LHS, RHS, S->getType())); } SVal VisitSymExpr(SymbolRef S) { return nonloc::SymbolVal(S); } |