Skip to content

Commit 8fc9c03

Browse files
authored
[analyzer] Revert Z3 changes (#95916)
Requested in: #95128 (comment) Revert "[analyzer] Harden safeguards for Z3 query times" Revert "[analyzer][NFC] Reorganize Z3 report refutation" This reverts commit eacc3b3. This reverts commit 89c26f6.
1 parent 55d5c03 commit 8fc9c03

File tree

14 files changed

+126
-602
lines changed

14 files changed

+126
-602
lines changed

clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -184,26 +184,6 @@ ANALYZER_OPTION(bool, ShouldCrosscheckWithZ3, "crosscheck-with-z3",
184184
"constraint manager backend.",
185185
false)
186186

187-
ANALYZER_OPTION(
188-
unsigned, Z3CrosscheckEQClassTimeoutThreshold,
189-
"crosscheck-with-z3-eqclass-timeout-threshold",
190-
"Set a timeout for bug report equivalence classes in milliseconds. "
191-
"If we exhaust this threshold, we will drop the bug report eqclass "
192-
"instead of doing more Z3 queries. Set 0 for no timeout.", 700)
193-
194-
ANALYZER_OPTION(
195-
unsigned, Z3CrosscheckTimeoutThreshold,
196-
"crosscheck-with-z3-timeout-threshold",
197-
"Set a timeout for individual Z3 queries in milliseconds. "
198-
"Set 0 for no timeout.", 300)
199-
200-
ANALYZER_OPTION(
201-
unsigned, Z3CrosscheckRLimitThreshold,
202-
"crosscheck-with-z3-rlimit-threshold",
203-
"Set the Z3 resource limit threshold. This sets a deterministic cutoff "
204-
"point for Z3 queries, as longer queries usually consume more resources. "
205-
"Set 0 for unlimited.", 400'000)
206-
207187
ANALYZER_OPTION(bool, ShouldReportIssuesInMainSourceFile,
208188
"report-in-main-source-file",
209189
"Whether or not the diagnostic report should be always "

clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,29 @@ class SuppressInlineDefensiveChecksVisitor final : public BugReporterVisitor {
597597
PathSensitiveBugReport &BR) override;
598598
};
599599

600+
/// The bug visitor will walk all the nodes in a path and collect all the
601+
/// constraints. When it reaches the root node, will create a refutation
602+
/// manager and check if the constraints are satisfiable
603+
class FalsePositiveRefutationBRVisitor final : public BugReporterVisitor {
604+
private:
605+
/// Holds the constraints in a given path
606+
ConstraintMap Constraints;
607+
608+
public:
609+
FalsePositiveRefutationBRVisitor();
610+
611+
void Profile(llvm::FoldingSetNodeID &ID) const override;
612+
613+
PathDiagnosticPieceRef VisitNode(const ExplodedNode *N,
614+
BugReporterContext &BRC,
615+
PathSensitiveBugReport &BR) override;
616+
617+
void finalizeVisitor(BugReporterContext &BRC, const ExplodedNode *EndPathNode,
618+
PathSensitiveBugReport &BR) override;
619+
void addConstraints(const ExplodedNode *N,
620+
bool OverwriteConstraintsOnExistingSyms);
621+
};
622+
600623
/// The visitor detects NoteTags and displays the event notes they contain.
601624
class TagVisitor : public BugReporterVisitor {
602625
public:

clang/include/clang/StaticAnalyzer/Core/BugReporter/Z3CrosscheckVisitor.h

Lines changed: 0 additions & 92 deletions
This file was deleted.

clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,7 @@ class SMTConstraintManager : public clang::ento::SimpleConstraintManager {
3434
public:
3535
SMTConstraintManager(clang::ento::ExprEngine *EE,
3636
clang::ento::SValBuilder &SB)
37-
: SimpleConstraintManager(EE, SB) {
38-
Solver->setBoolParam("model", true); // Enable model finding
39-
Solver->setUnsignedParam("timeout", 15000 /*milliseconds*/);
40-
}
37+
: SimpleConstraintManager(EE, SB) {}
4138
virtual ~SMTConstraintManager() = default;
4239

4340
//===------------------------------------------------------------------===//

clang/lib/StaticAnalyzer/Core/BugReporter.cpp

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
3636
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"
3737
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
38-
#include "clang/StaticAnalyzer/Core/BugReporter/Z3CrosscheckVisitor.h"
3938
#include "clang/StaticAnalyzer/Core/Checker.h"
4039
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
4140
#include "clang/StaticAnalyzer/Core/CheckerRegistryData.h"
@@ -87,14 +86,6 @@ STATISTIC(MaxValidBugClassSize,
8786
"The maximum number of bug reports in the same equivalence class "
8887
"where at least one report is valid (not suppressed)");
8988

90-
STATISTIC(NumTimesReportPassesZ3, "Number of reports passed Z3");
91-
STATISTIC(NumTimesReportRefuted, "Number of reports refuted by Z3");
92-
STATISTIC(NumTimesReportEQClassAborted,
93-
"Number of times a report equivalence class was aborted by the Z3 "
94-
"oracle heuristic");
95-
STATISTIC(NumTimesReportEQClassWasExhausted,
96-
"Number of times all reports of an equivalence class was refuted");
97-
9889
BugReporterVisitor::~BugReporterVisitor() = default;
9990

10091
void BugReporterContext::anchor() {}
@@ -2843,7 +2834,6 @@ generateVisitorsDiagnostics(PathSensitiveBugReport *R,
28432834
std::optional<PathDiagnosticBuilder> PathDiagnosticBuilder::findValidReport(
28442835
ArrayRef<PathSensitiveBugReport *> &bugReports,
28452836
PathSensitiveBugReporter &Reporter) {
2846-
Z3CrosscheckOracle Z3Oracle(Reporter.getAnalyzerOptions());
28472837

28482838
BugPathGetter BugGraph(&Reporter.getGraph(), bugReports);
28492839

@@ -2874,35 +2864,21 @@ std::optional<PathDiagnosticBuilder> PathDiagnosticBuilder::findValidReport(
28742864
// If crosscheck is enabled, remove all visitors, add the refutation
28752865
// visitor and check again
28762866
R->clearVisitors();
2877-
Z3CrosscheckVisitor::Z3Result CrosscheckResult;
2878-
R->addVisitor<Z3CrosscheckVisitor>(CrosscheckResult,
2879-
Reporter.getAnalyzerOptions());
2867+
R->addVisitor<FalsePositiveRefutationBRVisitor>();
28802868

28812869
// We don't overwrite the notes inserted by other visitors because the
28822870
// refutation manager does not add any new note to the path
28832871
generateVisitorsDiagnostics(R, BugPath->ErrorNode, BRC);
2884-
switch (Z3Oracle.interpretQueryResult(CrosscheckResult)) {
2885-
case Z3CrosscheckOracle::RejectReport:
2886-
++NumTimesReportRefuted;
2887-
R->markInvalid("Infeasible constraints", /*Data=*/nullptr);
2888-
continue;
2889-
case Z3CrosscheckOracle::RejectEQClass:
2890-
++NumTimesReportEQClassAborted;
2891-
return {};
2892-
case Z3CrosscheckOracle::AcceptReport:
2893-
++NumTimesReportPassesZ3;
2894-
break;
2895-
}
28962872
}
28972873

2898-
assert(R->isValid());
2899-
return PathDiagnosticBuilder(std::move(BRC), std::move(BugPath->BugPath),
2900-
BugPath->Report, BugPath->ErrorNode,
2901-
std::move(visitorNotes));
2874+
// Check if the bug is still valid
2875+
if (R->isValid())
2876+
return PathDiagnosticBuilder(
2877+
std::move(BRC), std::move(BugPath->BugPath), BugPath->Report,
2878+
BugPath->ErrorNode, std::move(visitorNotes));
29022879
}
29032880
}
29042881

2905-
++NumTimesReportEQClassWasExhausted;
29062882
return {};
29072883
}
29082884

clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3446,6 +3446,82 @@ UndefOrNullArgVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC,
34463446
return nullptr;
34473447
}
34483448

3449+
//===----------------------------------------------------------------------===//
3450+
// Implementation of FalsePositiveRefutationBRVisitor.
3451+
//===----------------------------------------------------------------------===//
3452+
3453+
FalsePositiveRefutationBRVisitor::FalsePositiveRefutationBRVisitor()
3454+
: Constraints(ConstraintMap::Factory().getEmptyMap()) {}
3455+
3456+
void FalsePositiveRefutationBRVisitor::finalizeVisitor(
3457+
BugReporterContext &BRC, const ExplodedNode *EndPathNode,
3458+
PathSensitiveBugReport &BR) {
3459+
// Collect new constraints
3460+
addConstraints(EndPathNode, /*OverwriteConstraintsOnExistingSyms=*/true);
3461+
3462+
// Create a refutation manager
3463+
llvm::SMTSolverRef RefutationSolver = llvm::CreateZ3Solver();
3464+
ASTContext &Ctx = BRC.getASTContext();
3465+
3466+
// Add constraints to the solver
3467+
for (const auto &I : Constraints) {
3468+
const SymbolRef Sym = I.first;
3469+
auto RangeIt = I.second.begin();
3470+
3471+
llvm::SMTExprRef SMTConstraints = SMTConv::getRangeExpr(
3472+
RefutationSolver, Ctx, Sym, RangeIt->From(), RangeIt->To(),
3473+
/*InRange=*/true);
3474+
while ((++RangeIt) != I.second.end()) {
3475+
SMTConstraints = RefutationSolver->mkOr(
3476+
SMTConstraints, SMTConv::getRangeExpr(RefutationSolver, Ctx, Sym,
3477+
RangeIt->From(), RangeIt->To(),
3478+
/*InRange=*/true));
3479+
}
3480+
3481+
RefutationSolver->addConstraint(SMTConstraints);
3482+
}
3483+
3484+
// And check for satisfiability
3485+
std::optional<bool> IsSAT = RefutationSolver->check();
3486+
if (!IsSAT)
3487+
return;
3488+
3489+
if (!*IsSAT)
3490+
BR.markInvalid("Infeasible constraints", EndPathNode->getLocationContext());
3491+
}
3492+
3493+
void FalsePositiveRefutationBRVisitor::addConstraints(
3494+
const ExplodedNode *N, bool OverwriteConstraintsOnExistingSyms) {
3495+
// Collect new constraints
3496+
ConstraintMap NewCs = getConstraintMap(N->getState());
3497+
ConstraintMap::Factory &CF = N->getState()->get_context<ConstraintMap>();
3498+
3499+
// Add constraints if we don't have them yet
3500+
for (auto const &C : NewCs) {
3501+
const SymbolRef &Sym = C.first;
3502+
if (!Constraints.contains(Sym)) {
3503+
// This symbol is new, just add the constraint.
3504+
Constraints = CF.add(Constraints, Sym, C.second);
3505+
} else if (OverwriteConstraintsOnExistingSyms) {
3506+
// Overwrite the associated constraint of the Symbol.
3507+
Constraints = CF.remove(Constraints, Sym);
3508+
Constraints = CF.add(Constraints, Sym, C.second);
3509+
}
3510+
}
3511+
}
3512+
3513+
PathDiagnosticPieceRef FalsePositiveRefutationBRVisitor::VisitNode(
3514+
const ExplodedNode *N, BugReporterContext &, PathSensitiveBugReport &) {
3515+
addConstraints(N, /*OverwriteConstraintsOnExistingSyms=*/false);
3516+
return nullptr;
3517+
}
3518+
3519+
void FalsePositiveRefutationBRVisitor::Profile(
3520+
llvm::FoldingSetNodeID &ID) const {
3521+
static int Tag = 0;
3522+
ID.AddPointer(&Tag);
3523+
}
3524+
34493525
//===----------------------------------------------------------------------===//
34503526
// Implementation of TagVisitor.
34513527
//===----------------------------------------------------------------------===//

clang/lib/StaticAnalyzer/Core/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ add_clang_library(clangStaticAnalyzerCore
5151
SymbolManager.cpp
5252
TextDiagnostics.cpp
5353
WorkList.cpp
54-
Z3CrosscheckVisitor.cpp
5554

5655
LINK_LIBS
5756
clangAST

0 commit comments

Comments
 (0)