mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-23 22:00:10 +00:00
[Analyzer][Core] Better simplification in SimpleSValBuilder::evalBinOpNN
Make the SValBuilder capable to simplify existing SVals based on a newly added constraints when evaluating a BinOp. Before this patch, we called `simplify` only in some edge cases. However, we can and should investigate the constraints in all cases. Differential Revision: https://reviews.llvm.org/D113753
This commit is contained in:
parent
e13246a2ec
commit
12887a2024
@ -372,6 +372,15 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
|
||||
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 @@ SVal SimpleSValBuilder::evalBinOpNN(ProgramStateRef state,
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
30
clang/test/Analysis/svalbuilder-simplify-in-evalbinop.cpp
Normal file
30
clang/test/Analysis/svalbuilder-simplify-in-evalbinop.cpp
Normal file
@ -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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user