[PATCH] D36564: [analyzer] Fix SimpleSValBuilder::simplifySVal
Alexander Shaposhnikov via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 9 17:21:10 PDT 2017
alexshap created this revision.
Herald added a subscriber: xazax.hun.
This diff attempts to address a crash (triggered assert) on the newly-added test case.
The assert being discussed is inside SValBuilder::evalBinOp
if (Optional<Loc> RV = rhs.getAs<Loc>()) {
// Support pointer arithmetic where the addend is on the left
// and the pointer on the right.
assert(op == BO_Add);
but the root cause seems to be in a different place (if I'm not missing smth).
The method simplifySVal appears to be doing the wrong thing for SVal "(char*)E - (char*)B".
Call stack: evalIntegralCast -> evalBinOpNN -> simplifySVal -> ... -> simplifySVal -> Simplifier::VisitSymSymExpr -> ...
Inside Simplifier::VisitSymSymExpr the call Visit(S->getLHS()) returns a NonLoc
(where S->getLHS() represents char* E) while the call Visit(S->getRHS()) returns a Loc.
For Visit(S->getRHS()) this happens because in VisitSymbolData(const SymbolData *S) the "if" condition
if (const llvm::APSInt *I =
SVB.getKnownValue(State, nonloc::SymbolVal(S)))
is satisfied and Loc is correctly chosen.
For Visit(S->getLHS()) nonloc::SymbolVal(S) is used instead.
Next those values will passed to SValBuilder::evalBinOp and the code path
if (Optional<Loc> RV = rhs.getAs<Loc>()) {
// Support pointer arithmetic where the addend is on the left
// and the pointer on the right.
assert(op == BO_Add);
// Commute the operands.
return evalBinOpLN(state, op, *RV, lhs.castAs<NonLoc>(), type);
}
is executed instead of
if (Optional<Loc> LV = lhs.getAs<Loc>()) {
if (Optional<Loc> RV = rhs.getAs<Loc>())
return evalBinOpLL(state, op, *LV, *RV, type);
return evalBinOpLN(state, op, *LV, rhs.castAs<NonLoc>(), type);
}
Test plan: make check-all (green)
Repository:
rL LLVM
https://reviews.llvm.org/D36564
Files:
lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
test/Analysis/ptr-arith.cpp
Index: test/Analysis/ptr-arith.cpp
===================================================================
--- test/Analysis/ptr-arith.cpp
+++ test/Analysis/ptr-arith.cpp
@@ -98,3 +98,10 @@
int a[5][5];
*(*(a+1)+2) = 2;
}
+
+unsigned ptrSubtractionNoCrash(char *Begin, char *End) {
+ auto N = End - Begin;
+ if (Begin)
+ return 0;
+ return N;
+}
Index: lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
===================================================================
--- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -1016,7 +1016,8 @@
SVB.getKnownValue(State, nonloc::SymbolVal(S)))
return Loc::isLocType(S->getType()) ? (SVal)SVB.makeIntLocVal(*I)
: (SVal)SVB.makeIntVal(*I);
- return nonloc::SymbolVal(S);
+ return Loc::isLocType(S->getType()) ? (SVal)SVB.makeLoc(S)
+ : nonloc::SymbolVal(S);
}
// TODO: Support SymbolCast. Support IntSymExpr when/if we actually
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D36564.110502.patch
Type: text/x-patch
Size: 1062 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170810/55e5e9e3/attachment.bin>
More information about the cfe-commits
mailing list