mirror of
https://github.com/intel/llvm.git
synced 2026-01-20 10:58:11 +08:00
[analyzer] SValBuilder::evalBinOpLN: try simplifying the RHS first (#161537)
The first thing `SValBuilder::evalBinOpNN` does is simplify both operators ([here](https://github.com/llvm/llvm-project/blob/main/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp#L430-L437)), why wouldn't we simplify the RHS in `SValBuilder::evalBinOpLN`? When the LHS is an `Element`, the right side is simplified incidentally when calling `evalBinOpNN` ([here](https://github.com/llvm/llvm-project/blob/main/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp#L1169-L1170)). Without this patch, the “base_complex” test case is **UNKNOWN** instead of **TRUE**.
This commit is contained in:
committed by
GitHub
parent
a8057ff129
commit
d49aa40fc7
@@ -1111,6 +1111,10 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
|
||||
assert(!BinaryOperator::isComparisonOp(op) &&
|
||||
"arguments to comparison ops must be of the same type");
|
||||
|
||||
SVal simplifiedRhs = simplifySVal(state, rhs);
|
||||
if (auto simplifiedRhsAsNonLoc = simplifiedRhs.getAs<NonLoc>())
|
||||
rhs = *simplifiedRhsAsNonLoc;
|
||||
|
||||
// Special case: rhs is a zero constant.
|
||||
if (rhs.isZeroConstant())
|
||||
return lhs;
|
||||
|
||||
61
clang/test/Analysis/loc-folding.cpp
Normal file
61
clang/test/Analysis/loc-folding.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
// RUN: %clang_analyze_cc1 -verify %s -analyzer-config eagerly-assume=false \
|
||||
// RUN: -analyzer-checker=core,debug.ExprInspection
|
||||
|
||||
void clang_analyzer_eval(bool);
|
||||
|
||||
void element_constant() {
|
||||
char arr[10];
|
||||
clang_analyzer_eval(arr + 1 > arr); // expected-warning{{TRUE}}
|
||||
}
|
||||
|
||||
void element_known() {
|
||||
char arr[10];
|
||||
int off = 1;
|
||||
clang_analyzer_eval(arr + off > arr); // expected-warning{{TRUE}}
|
||||
}
|
||||
|
||||
void element_constrained(int off) {
|
||||
char arr[10];
|
||||
if (off == 1) {
|
||||
clang_analyzer_eval(arr + off > arr); // expected-warning{{TRUE}}
|
||||
}
|
||||
}
|
||||
|
||||
void element_unknown(int off) {
|
||||
char arr[10];
|
||||
clang_analyzer_eval(arr + off > arr); // expected-warning{{UNKNOWN}}
|
||||
}
|
||||
|
||||
void element_complex(int off) {
|
||||
char arr[10];
|
||||
int comp = off * 2;
|
||||
if (off == 1) {
|
||||
clang_analyzer_eval(arr + comp); // expected-warning{{TRUE}}
|
||||
}
|
||||
}
|
||||
|
||||
void base_constant(int *arr) {
|
||||
clang_analyzer_eval(arr + 1 > arr); // expected-warning{{TRUE}}
|
||||
}
|
||||
|
||||
void base_known(int *arr) {
|
||||
int off = 1;
|
||||
clang_analyzer_eval(arr + off > arr); // expected-warning{{TRUE}}
|
||||
}
|
||||
|
||||
void base_constrained(int *arr, int off) {
|
||||
if (off == 1) {
|
||||
clang_analyzer_eval(arr + off > arr); // expected-warning{{TRUE}}
|
||||
}
|
||||
}
|
||||
|
||||
void base_unknown(int *arr, int off) {
|
||||
clang_analyzer_eval(arr + off > arr); // expected-warning{{UNKNOWN}}
|
||||
}
|
||||
|
||||
void base_complex(int *arr, int off) {
|
||||
int comp = off * 2;
|
||||
if (off == 1) {
|
||||
clang_analyzer_eval(arr + comp > arr); // expected-warning{{TRUE}}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user