diff --git a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp --- a/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -1183,6 +1183,19 @@ S, SVB.evalBinOp(State, S->getOpcode(), LHS, RHS, S->getType())); } + SVal VisitIntSymExpr(const IntSymExpr *S) { + auto I = Cached.find(S); + if (I != Cached.end()) + return I->second; + + SVal RHS = Visit(S->getRHS()); + if (isUnchanged(S->getRHS(), RHS)) + return skip(S); + SVal LHS = SVB.makeIntVal(S->getLHS()); + return cache( + S, SVB.evalBinOp(State, S->getOpcode(), LHS, RHS, S->getType())); + } + SVal VisitSymSymExpr(const SymSymExpr *S) { auto I = Cached.find(S); if (I != Cached.end()) diff --git a/clang/test/Analysis/svalbuilder-simplify-intsym.cpp b/clang/test/Analysis/svalbuilder-simplify-intsym.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Analysis/svalbuilder-simplify-intsym.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_analyze_cc1 %s \ +// RUN: -analyzer-checker=core \ +// RUN: -analyzer-checker=debug.ExprInspection \ +// RUN: -analyzer-config eagerly-assume=false \ +// RUN: -verify + +// Here we test whether the SValBuilder is capable to simplify existing +// IntSym expressions based on a newly added constraint on the sub-expression. + +void clang_analyzer_eval(bool); + +void test_SValBuilder_simplifies_IntSym(int x, int y) { + // Most IntSym BinOps are transformed to SymInt in SimpleSValBuilder. + // Division is one exception. + x = 77 / y; + if (y != 1) + return; + clang_analyzer_eval(x == 77); // expected-warning{{TRUE}} + (void)(x * y); +}