https://github.com/steakhal updated https://github.com/llvm/llvm-project/pull/112583
>From dfb86a3ddad88a9a97fff054af1bf86d746ee49d Mon Sep 17 00:00:00 2001 From: Balazs Benics <benicsbal...@gmail.com> Date: Wed, 16 Oct 2024 15:52:31 +0200 Subject: [PATCH] [analyzer][Solver] Improve getSymVal and friends (1/2) 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. --- .../Checkers/BitwiseShiftChecker.cpp | 3 +- .../Core/RangeConstraintManager.cpp | 21 +++++--------- clang/test/Analysis/infeasible-sink.c | 29 +++---------------- 3 files changed, 14 insertions(+), 39 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/BitwiseShiftChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/BitwiseShiftChecker.cpp index 339927c165fe00..17f1214195b3ee 100644 --- a/clang/lib/StaticAnalyzer/Checkers/BitwiseShiftChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/BitwiseShiftChecker.cpp @@ -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()); } } diff --git a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp index 70d5a609681790..ecf7974c838650 100644 --- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp +++ b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp @@ -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, @@ -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(); } //===----------------------------------------------------------------------===// diff --git a/clang/test/Analysis/infeasible-sink.c b/clang/test/Analysis/infeasible-sink.c index 9cb66fcac0b6be..a88ca42f27e441 100644 --- a/clang/test/Analysis/infeasible-sink.c +++ b/clang/test/Analysis/infeasible-sink.c @@ -38,7 +38,7 @@ void test1(int x) { } int a, b, c, d, e; -void test2() { +void test2(void) { if (a == 0) return; @@ -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. } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits