Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
61 changes: 61 additions & 0 deletions clang/test/Analysis/loc-folding.cpp
Original file line number Diff line number Diff line change
@@ -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}}
}
}