clang 24.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
19
20namespace clang::ento {
21
22/// The bug visitor will walk all the nodes in a path and collect all the
23/// constraints. When it reaches the root node, will create a refutation
24/// manager and check if the constraints are satisfiable.
26public:
27 struct Z3Result {
28 std::optional<bool> IsSAT = std::nullopt;
30 unsigned UsedRLimit = 0;
31 };
33 const AnalyzerOptions &Opts);
34
35 void Profile(llvm::FoldingSetNodeID &ID) const override;
36
39 PathSensitiveBugReport &BR) override;
40
41 void finalizeVisitor(const ExplodedNode *EndPathNode, BugReporterContext &BRC,
42 PathSensitiveBugReport &BR) override;
43
44private:
45 void addConstraints(const ExplodedNode *N,
46 bool OverwriteConstraintsOnExistingSyms);
47
48 /// Holds the constraints in a given path.
49 ConstraintMap Constraints;
50 Z3Result &Result;
51 const AnalyzerOptions &Opts;
52};
53
54/// The oracle will decide if a report should be accepted or rejected based on
55/// the results of the Z3 solver and the statistics of the queries of a report
56/// equivalenece class.
58public:
59 explicit Z3CrosscheckOracle(const AnalyzerOptions &Opts) : Opts(Opts) {}
60
62 AcceptReport, // The report was SAT.
63 RejectReport, // The report was UNSAT or UNDEF.
64 RejectEQClass, // The heuristic suggests to skip the current eqclass.
65 };
66
67 /// Updates the internal state with the new Z3Result and makes a decision how
68 /// to proceed:
69 /// - Accept the report if the Z3Result was SAT.
70 /// - Suggest dropping the report equvalence class based on the accumulated
71 /// statistics.
72 /// - Otherwise, reject the report if the Z3Result was UNSAT or UNDEF.
73 ///
74 /// Conditions for dropping the equivalence class:
75 /// - Accumulative time spent in Z3 checks is more than 700ms in the eqclass.
76 /// - Hit the 300ms query timeout in the report eqclass.
77 /// - Hit the 400'000 rlimit in the report eqclass.
78 ///
79 /// All these thresholds are configurable via the analyzer options.
80 ///
81 /// Refer to
82 /// https://discourse.llvm.org/t/analyzer-rfc-taming-z3-query-times/79520 to
83 /// see why this heuristic was chosen.
85
86private:
87 const AnalyzerOptions &Opts;
88 unsigned AccumulatedZ3QueryTimeInEqClass = 0; // ms
89};
90
91} // namespace clang::ento
92
93#endif // LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_Z3CROSSCHECKVISITOR_H
Stores options for the analyzer from the command line.
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:
void finalizeVisitor(const ExplodedNode *EndPathNode, BugReporterContext &BRC, PathSensitiveBugReport &BR) override
Last function called on the visitor, no further calls to VisitNode would follow.
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
Z3CrosscheckVisitor(Z3CrosscheckVisitor::Z3Result &Result, const AnalyzerOptions &Opts)
llvm::ImmutableMap< SymbolRef, RangeSet > ConstraintMap
std::shared_ptr< PathDiagnosticPiece > PathDiagnosticPieceRef