Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 6 additions & 0 deletions clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1111,6 +1111,12 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
assert(!BinaryOperator::isComparisonOp(op) &&
"arguments to comparison ops must be of the same type");

// Constraints may have changed since the creation of a bound SVal. Check if
// the value can be simplified based on those new constraints.
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
60 changes: 60 additions & 0 deletions clang/test/Analysis/loc-folding.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -Wno-tautological-compare -analyzer-config eagerly-assume=false %s

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}}
}
}