Skip to content

Commit 1aeac20

Browse files
[analyzer] SValBuilder::evalBinOpLN: try simplifying the RHS first
1 parent 372d3fb commit 1aeac20

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,6 +1111,12 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
11111111
assert(!BinaryOperator::isComparisonOp(op) &&
11121112
"arguments to comparison ops must be of the same type");
11131113

1114+
// Constraints may have changed since the creation of a bound SVal. Check if
1115+
// the value can be simplified based on those new constraints.
1116+
SVal simplifiedRhs = simplifySVal(state, rhs);
1117+
if (auto simplifiedRhsAsNonLoc = simplifiedRhs.getAs<NonLoc>())
1118+
rhs = *simplifiedRhsAsNonLoc;
1119+
11141120
// Special case: rhs is a zero constant.
11151121
if (rhs.isZeroConstant())
11161122
return lhs;
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -Wno-tautological-compare -analyzer-config eagerly-assume=false %s
2+
3+
void clang_analyzer_eval(bool);
4+
5+
void element_constant() {
6+
char arr[10];
7+
clang_analyzer_eval(arr + 1 > arr); // expected-warning{{TRUE}}
8+
}
9+
10+
void element_known() {
11+
char arr[10];
12+
int off = 1;
13+
clang_analyzer_eval(arr + off > arr); // expected-warning{{TRUE}}
14+
}
15+
16+
void element_constrained(int off) {
17+
char arr[10];
18+
if (off == 1) {
19+
clang_analyzer_eval(arr + off > arr); // expected-warning{{TRUE}}
20+
}
21+
}
22+
23+
void element_unknown(int off) {
24+
char arr[10];
25+
clang_analyzer_eval(arr + off > arr); // expected-warning{{UNKNOWN}}
26+
}
27+
28+
void element_complex(int off) {
29+
char arr[10];
30+
int comp = off * 2;
31+
if (off == 1) {
32+
clang_analyzer_eval(arr + comp); // expected-warning{{TRUE}}
33+
}
34+
}
35+
36+
void base_constant(int *arr) {
37+
clang_analyzer_eval(arr + 1 > arr); // expected-warning{{TRUE}}
38+
}
39+
40+
void base_known(int *arr) {
41+
int off = 1;
42+
clang_analyzer_eval(arr + off > arr); // expected-warning{{TRUE}}
43+
}
44+
45+
void base_constrained(int *arr, int off) {
46+
if (off == 1) {
47+
clang_analyzer_eval(arr + off > arr); // expected-warning{{TRUE}}
48+
}
49+
}
50+
51+
void base_unknown(int *arr, int off) {
52+
clang_analyzer_eval(arr + off > arr); // expected-warning{{UNKNOWN}}
53+
}
54+
55+
void base_complex(int *arr, int off) {
56+
int comp = off * 2;
57+
if (off == 1) {
58+
clang_analyzer_eval(arr + comp > arr); // expected-warning{{TRUE}}
59+
}
60+
}

0 commit comments

Comments
 (0)