clang 20.0.0git
Z3CrosscheckVisitor.h
Go to the documentation of this file.
1//===- Z3CrosscheckVisitor.h - Crosscheck reports with Z3 -------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the visitor and utilities around it for Z3 report
10// refutation.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_Z3CROSSCHECKVISITOR_H
15#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_Z3CROSSCHECKVISITOR_H
16
18
19namespace clang::ento {
20
21/// The bug visitor will walk all the nodes in a path and collect all the
22/// constraints. When it reaches the root node, will create a refutation
23/// manager and check if the constraints are satisfiable.
25public:
26 struct Z3Result {
27 std::optional<bool> IsSAT = std::nullopt;
29 unsigned UsedRLimit = 0;
30 };
32 const AnalyzerOptions &Opts);
33
34 void Profile(llvm::FoldingSetNodeID &ID) const override;
35
38 PathSensitiveBugReport &BR) override;
39
40 void finalizeVisitor(BugReporterContext &BRC, const ExplodedNode *EndPathNode,
41 PathSensitiveBugReport &BR) override;
42
43private:
44 void addConstraints(const ExplodedNode *N,
45 bool OverwriteConstraintsOnExistingSyms);
46
47 /// Holds the constraints in a given path.
48 ConstraintMap Constraints;
49 Z3Result &Result;
50 const AnalyzerOptions &Opts;
51};
52
53/// The oracle will decide if a report should be accepted or rejected based on
54/// the results of the Z3 solver and the statistics of the queries of a report
55/// equivalenece class.
57public:
58 explicit Z3CrosscheckOracle(const AnalyzerOptions &Opts) : Opts(Opts) {}
59
61 AcceptReport, // The report was SAT.
62 RejectReport, // The report was UNSAT or UNDEF.
63 RejectEQClass, // The heuristic suggests to skip the current eqclass.
64 };
65
66 /// Updates the internal state with the new Z3Result and makes a decision how
67 /// to proceed:
68 /// - Accept the report if the Z3Result was SAT.
69 /// - Suggest dropping the report equvalence class based on the accumulated
70 /// statistics.
71 /// - Otherwise, reject the report if the Z3Result was UNSAT or UNDEF.
72 ///
73 /// Conditions for dropping the equivalence class:
74 /// - Accumulative time spent in Z3 checks is more than 700ms in the eqclass.
75 /// - Hit the 300ms query timeout in the report eqclass.
76 /// - Hit the 400'000 rlimit in the report eqclass.
77 ///
78 /// All these thresholds are configurable via the analyzer options.
79 ///
80 /// Refer to
81 /// https://discourse.llvm.org/t/analyzer-rfc-taming-z3-query-times/79520 to
82 /// see why this heuristic was chosen.
84
85private:
86 const AnalyzerOptions &Opts;
87 unsigned AccumulatedZ3QueryTimeInEqClass = 0; // ms
88};
89
90} // namespace clang::ento
91
92#endif // LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_Z3CROSSCHECKVISITOR_H
static char ID
Definition: Arena.cpp:183
Stores options for the analyzer from the command line.
BugReporterVisitors are used to add custom diagnostics along a path.
The oracle will decide if a report should be accepted or rejected based on the results of the Z3 solv...
Z3CrosscheckOracle(const AnalyzerOptions &Opts)
Z3Decision interpretQueryResult(const Z3CrosscheckVisitor::Z3Result &Meta)
Updates the internal state with the new Z3Result and makes a decision how to proceed:
The bug visitor will walk all the nodes in a path and collect all the constraints.
PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
void Profile(llvm::FoldingSetNodeID &ID) const override
void finalizeVisitor(BugReporterContext &BRC, const ExplodedNode *EndPathNode, PathSensitiveBugReport &BR) override
Last function called on the visitor, no further calls to VisitNode would follow.
llvm::ImmutableMap< SymbolRef, RangeSet > ConstraintMap
std::shared_ptr< PathDiagnosticPiece > PathDiagnosticPieceRef