Skip to content

Commit 4bf74c7

Browse files
committed
[analyzer][Solver] Improve getSymVal and friends
Instead of just doing a lookup in the existing constraints, let's use `getRange()` for dissambling SymSymExprs and inferring from the constraint system what end range set we can simplify. This means that `getSymVal` gets more expensive while getting smarter. I don't expect it to be an issue as this API is only rarely used, and `getRange` is used a lot more often - yet without any observable hit on performance. This patch also removes dead declarations of EQClass overloads.
1 parent 91b5bef commit 4bf74c7

File tree

2 files changed

+12
-22
lines changed

2 files changed

+12
-22
lines changed

clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1939,11 +1939,8 @@ class RangeConstraintManager : public RangedConstraintManager {
19391939
RangeSet::Factory F;
19401940

19411941
RangeSet getRange(ProgramStateRef State, SymbolRef Sym);
1942-
RangeSet getRange(ProgramStateRef State, EquivalenceClass Class);
19431942
ProgramStateRef setRange(ProgramStateRef State, SymbolRef Sym,
19441943
RangeSet Range);
1945-
ProgramStateRef setRange(ProgramStateRef State, EquivalenceClass Class,
1946-
RangeSet Range);
19471944

19481945
RangeSet getSymLTRange(ProgramStateRef St, SymbolRef Sym,
19491946
const llvm::APSInt &Int,
@@ -2866,12 +2863,14 @@ ConditionTruthVal RangeConstraintManager::checkNull(ProgramStateRef State,
28662863

28672864
const llvm::APSInt *RangeConstraintManager::getSymVal(ProgramStateRef St,
28682865
SymbolRef Sym) const {
2869-
const RangeSet *T = getConstraint(St, Sym);
2870-
return T ? T->getConcreteValue() : nullptr;
2866+
auto &MutableSelf = const_cast<RangeConstraintManager &>(*this);
2867+
return MutableSelf.getRange(St, Sym).getConcreteValue();
28712868
}
28722869

28732870
const llvm::APSInt *RangeConstraintManager::getSymMinVal(ProgramStateRef St,
28742871
SymbolRef Sym) const {
2872+
// TODO: Use `getRange()` like in `getSymVal()`, but that would make some
2873+
// of the reports of `BitwiseShiftChecker` look awkward.
28752874
const RangeSet *T = getConstraint(St, Sym);
28762875
if (!T || T->isEmpty())
28772876
return nullptr;
@@ -2880,6 +2879,8 @@ const llvm::APSInt *RangeConstraintManager::getSymMinVal(ProgramStateRef St,
28802879

28812880
const llvm::APSInt *RangeConstraintManager::getSymMaxVal(ProgramStateRef St,
28822881
SymbolRef Sym) const {
2882+
// TODO: Use `getRange()` like in `getSymVal()`, but that would make some
2883+
// of the reports of `BitwiseShiftChecker` look awkward.
28832884
const RangeSet *T = getConstraint(St, Sym);
28842885
if (!T || T->isEmpty())
28852886
return nullptr;

clang/test/Analysis/infeasible-sink.c

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ void test1(int x) {
3838
}
3939

4040
int a, b, c, d, e;
41-
void test2() {
41+
void test2(void) {
4242

4343
if (a == 0)
4444
return;
@@ -50,28 +50,17 @@ void test2() {
5050
b = d;
5151
a -= d;
5252

53+
clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}
54+
5355
if (a != 0)
5456
return;
5557

56-
clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
57-
58-
/* The BASELINE passes these checks ('wrning' is used to avoid lit to match)
59-
// The parent state is already infeasible, look at this contradiction:
60-
clang_analyzer_eval(b > 0); // expected-wrning{{FALSE}}
61-
clang_analyzer_eval(b <= 0); // expected-wrning{{FALSE}}
62-
// Crashes with expensive checks.
63-
if (b > 0) {
64-
clang_analyzer_warnIfReached(); // no-warning, OK
65-
return;
66-
}
67-
// Should not be reachable.
68-
clang_analyzer_warnIfReached(); // expected-wrning{{REACHABLE}}
69-
*/
58+
clang_analyzer_warnIfReached(); // no-warning: Even the parent state is unreachable.
7059

7160
// The parent state is already infeasible, but we realize that only if b is
7261
// constrained.
73-
clang_analyzer_eval(b > 0); // expected-warning{{UNKNOWN}}
74-
clang_analyzer_eval(b <= 0); // expected-warning{{UNKNOWN}}
62+
clang_analyzer_eval(b > 0); // no-warning
63+
clang_analyzer_eval(b <= 0); // no-warning
7564
if (b > 0) {
7665
clang_analyzer_warnIfReached(); // no-warning
7766
return;

0 commit comments

Comments
 (0)