Skip to content

[analyzer][Solver] Improve getSymVal and friends (1/2) #112583

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 18, 2024
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
3 changes: 2 additions & 1 deletion clang/lib/StaticAnalyzer/Checkers/BitwiseShiftChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ BugReportPtr BitwiseShiftValidator::checkOvershift() {
RightOpStr = formatv(" '{0}'", ConcreteRight->getValue());
else {
SValBuilder &SVB = Ctx.getSValBuilder();
if (const llvm::APSInt *MinRight = SVB.getMinValue(FoldedState, Right)) {
if (const llvm::APSInt *MinRight = SVB.getMinValue(FoldedState, Right);
MinRight && *MinRight >= LHSBitWidth) {
LowerBoundStr = formatv(" >= {0},", MinRight->getExtValue());
}
}
Expand Down
21 changes: 8 additions & 13 deletions clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1939,11 +1939,8 @@ class RangeConstraintManager : public RangedConstraintManager {
RangeSet::Factory F;

RangeSet getRange(ProgramStateRef State, SymbolRef Sym);
RangeSet getRange(ProgramStateRef State, EquivalenceClass Class);
ProgramStateRef setRange(ProgramStateRef State, SymbolRef Sym,
RangeSet Range);
ProgramStateRef setRange(ProgramStateRef State, EquivalenceClass Class,
RangeSet Range);

RangeSet getSymLTRange(ProgramStateRef St, SymbolRef Sym,
const llvm::APSInt &Int,
Expand Down Expand Up @@ -2866,24 +2863,22 @@ ConditionTruthVal RangeConstraintManager::checkNull(ProgramStateRef State,

const llvm::APSInt *RangeConstraintManager::getSymVal(ProgramStateRef St,
SymbolRef Sym) const {
const RangeSet *T = getConstraint(St, Sym);
return T ? T->getConcreteValue() : nullptr;
auto &MutableSelf = const_cast<RangeConstraintManager &>(*this);
return MutableSelf.getRange(St, Sym).getConcreteValue();
}

const llvm::APSInt *RangeConstraintManager::getSymMinVal(ProgramStateRef St,
SymbolRef Sym) const {
const RangeSet *T = getConstraint(St, Sym);
if (!T || T->isEmpty())
return nullptr;
return &T->getMinValue();
auto &MutableSelf = const_cast<RangeConstraintManager &>(*this);
RangeSet Range = MutableSelf.getRange(St, Sym);
return Range.isEmpty() ? nullptr : &Range.getMinValue();
}

const llvm::APSInt *RangeConstraintManager::getSymMaxVal(ProgramStateRef St,
SymbolRef Sym) const {
const RangeSet *T = getConstraint(St, Sym);
if (!T || T->isEmpty())
return nullptr;
return &T->getMaxValue();
auto &MutableSelf = const_cast<RangeConstraintManager &>(*this);
RangeSet Range = MutableSelf.getRange(St, Sym);
return Range.isEmpty() ? nullptr : &Range.getMaxValue();
}

//===----------------------------------------------------------------------===//
Expand Down
29 changes: 4 additions & 25 deletions clang/test/Analysis/infeasible-sink.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ void test1(int x) {
}

int a, b, c, d, e;
void test2() {
void test2(void) {

if (a == 0)
return;
Expand All @@ -50,31 +50,10 @@ void test2() {
b = d;
a -= d;

if (a != 0)
return;

clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
clang_analyzer_warnIfReached(); // expected-warning {{REACHABLE}}

/* The BASELINE passes these checks ('wrning' is used to avoid lit to match)
// The parent state is already infeasible, look at this contradiction:
clang_analyzer_eval(b > 0); // expected-wrning{{FALSE}}
clang_analyzer_eval(b <= 0); // expected-wrning{{FALSE}}
// Crashes with expensive checks.
if (b > 0) {
clang_analyzer_warnIfReached(); // no-warning, OK
if (a != 0)
return;
}
// Should not be reachable.
clang_analyzer_warnIfReached(); // expected-wrning{{REACHABLE}}
*/

// The parent state is already infeasible, but we realize that only if b is
// constrained.
clang_analyzer_eval(b > 0); // expected-warning{{UNKNOWN}}
clang_analyzer_eval(b <= 0); // expected-warning{{UNKNOWN}}
if (b > 0) {
clang_analyzer_warnIfReached(); // no-warning
return;
}
clang_analyzer_warnIfReached(); // no-warning
clang_analyzer_warnIfReached(); // no-warning: Unreachable due to contradiction.
}
Loading