martong updated this revision to Diff 389186. martong marked an inline comment as done. martong added a comment.
- Add new test case Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D113753/new/ https://reviews.llvm.org/D113753 Files: clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp clang/test/Analysis/svalbuilder-simplify-in-evalbinop.cpp Index: clang/test/Analysis/svalbuilder-simplify-in-evalbinop.cpp =================================================================== --- /dev/null +++ clang/test/Analysis/svalbuilder-simplify-in-evalbinop.cpp @@ -0,0 +1,30 @@ +// 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 +// SVals based on a newly added constraints when evaluating a BinOp. + +void clang_analyzer_eval(bool); + +void test_evalBinOp_simplifies_lhs(int y) { + int x = y / 77; + if (y != 77) + return; + + // Below `x` is the LHS being simplified. + clang_analyzer_eval(x == 1); // expected-warning{{TRUE}} + (void)(x * y); +} + +void test_evalBinOp_simplifies_rhs(int y) { + int x = y / 77; + if (y != 77) + return; + + // Below `x` is the RHS being simplified. + clang_analyzer_eval(1 == x); // expected-warning{{TRUE}} + (void)(x * y); +} Index: clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -372,6 +372,15 @@ NonLoc InputLHS = lhs; NonLoc InputRHS = rhs; + // Constraints may have changed since the creation of a bound SVal. Check if + // the values can be simplified based on those new constraints. + SVal simplifiedLhs = simplifySVal(state, lhs); + SVal simplifiedRhs = simplifySVal(state, rhs); + if (auto simplifiedLhsAsNonLoc = simplifiedLhs.getAs<NonLoc>()) + lhs = *simplifiedLhsAsNonLoc; + if (auto simplifiedRhsAsNonLoc = simplifiedRhs.getAs<NonLoc>()) + rhs = *simplifiedRhsAsNonLoc; + // Handle trivial case where left-side and right-side are the same. if (lhs == rhs) switch (op) { @@ -619,16 +628,6 @@ } } - // Does the symbolic expression simplify to a constant? - // If so, "fold" the constant by setting 'lhs' to a ConcreteInt - // and try again. - SVal simplifiedLhs = simplifySVal(state, lhs); - if (simplifiedLhs != lhs) - if (auto simplifiedLhsAsNonLoc = simplifiedLhs.getAs<NonLoc>()) { - lhs = *simplifiedLhsAsNonLoc; - continue; - } - // Is the RHS a constant? if (const llvm::APSInt *RHSValue = getKnownValue(state, rhs)) return MakeSymIntVal(Sym, op, *RHSValue, resultTy);
Index: clang/test/Analysis/svalbuilder-simplify-in-evalbinop.cpp =================================================================== --- /dev/null +++ clang/test/Analysis/svalbuilder-simplify-in-evalbinop.cpp @@ -0,0 +1,30 @@ +// 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 +// SVals based on a newly added constraints when evaluating a BinOp. + +void clang_analyzer_eval(bool); + +void test_evalBinOp_simplifies_lhs(int y) { + int x = y / 77; + if (y != 77) + return; + + // Below `x` is the LHS being simplified. + clang_analyzer_eval(x == 1); // expected-warning{{TRUE}} + (void)(x * y); +} + +void test_evalBinOp_simplifies_rhs(int y) { + int x = y / 77; + if (y != 77) + return; + + // Below `x` is the RHS being simplified. + clang_analyzer_eval(1 == x); // expected-warning{{TRUE}} + (void)(x * y); +} Index: clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp +++ clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp @@ -372,6 +372,15 @@ NonLoc InputLHS = lhs; NonLoc InputRHS = rhs; + // Constraints may have changed since the creation of a bound SVal. Check if + // the values can be simplified based on those new constraints. + SVal simplifiedLhs = simplifySVal(state, lhs); + SVal simplifiedRhs = simplifySVal(state, rhs); + if (auto simplifiedLhsAsNonLoc = simplifiedLhs.getAs<NonLoc>()) + lhs = *simplifiedLhsAsNonLoc; + if (auto simplifiedRhsAsNonLoc = simplifiedRhs.getAs<NonLoc>()) + rhs = *simplifiedRhsAsNonLoc; + // Handle trivial case where left-side and right-side are the same. if (lhs == rhs) switch (op) { @@ -619,16 +628,6 @@ } } - // Does the symbolic expression simplify to a constant? - // If so, "fold" the constant by setting 'lhs' to a ConcreteInt - // and try again. - SVal simplifiedLhs = simplifySVal(state, lhs); - if (simplifiedLhs != lhs) - if (auto simplifiedLhsAsNonLoc = simplifiedLhs.getAs<NonLoc>()) { - lhs = *simplifiedLhsAsNonLoc; - continue; - } - // Is the RHS a constant? if (const llvm::APSInt *RHSValue = getKnownValue(state, rhs)) return MakeSymIntVal(Sym, op, *RHSValue, resultTy);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits