Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===-- UncheckedOptionalAccessModel.h --------------------------*- 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 a dataflow analysis that detects unsafe uses of optional |
||
10 | // values. |
||
11 | // |
||
12 | //===----------------------------------------------------------------------===// |
||
13 | |||
14 | #ifndef CLANG_ANALYSIS_FLOWSENSITIVE_MODELS_UNCHECKEDOPTIONALACCESSMODEL_H |
||
15 | #define CLANG_ANALYSIS_FLOWSENSITIVE_MODELS_UNCHECKEDOPTIONALACCESSMODEL_H |
||
16 | |||
17 | #include "clang/AST/ASTContext.h" |
||
18 | #include "clang/Analysis/CFG.h" |
||
19 | #include "clang/Analysis/FlowSensitive/CFGMatchSwitch.h" |
||
20 | #include "clang/Analysis/FlowSensitive/DataflowAnalysis.h" |
||
21 | #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" |
||
22 | #include "clang/Analysis/FlowSensitive/NoopLattice.h" |
||
23 | #include "clang/Basic/SourceLocation.h" |
||
24 | #include <vector> |
||
25 | |||
26 | namespace clang { |
||
27 | namespace dataflow { |
||
28 | |||
29 | // FIXME: Explore using an allowlist-approach, where constructs supported by the |
||
30 | // analysis are always enabled and additional constructs are enabled through the |
||
31 | // `Options`. |
||
32 | struct UncheckedOptionalAccessModelOptions { |
||
33 | /// In generating diagnostics, ignore optionals reachable through overloaded |
||
34 | /// `operator*` or `operator->` (other than those of the optional type |
||
35 | /// itself). The analysis does not equate the results of such calls, so it |
||
36 | /// can't identify when their results are used safely (across calls), |
||
37 | /// resulting in false positives in all such cases. Note: this option does not |
||
38 | /// cover access through `operator[]`. |
||
39 | bool IgnoreSmartPointerDereference = false; |
||
40 | }; |
||
41 | |||
42 | /// Dataflow analysis that models whether optionals hold values or not. |
||
43 | /// |
||
44 | /// Models the `std::optional`, `absl::optional`, and `base::Optional` types. |
||
45 | class UncheckedOptionalAccessModel |
||
46 | : public DataflowAnalysis<UncheckedOptionalAccessModel, NoopLattice> { |
||
47 | public: |
||
48 | UncheckedOptionalAccessModel(ASTContext &Ctx); |
||
49 | |||
50 | /// Returns a matcher for the optional classes covered by this model. |
||
51 | static ast_matchers::DeclarationMatcher optionalClassDecl(); |
||
52 | |||
53 | static NoopLattice initialElement() { return {}; } |
||
54 | |||
55 | void transfer(const CFGElement *Elt, NoopLattice &L, Environment &Env); |
||
56 | |||
57 | ComparisonResult compare(QualType Type, const Value &Val1, |
||
58 | const Environment &Env1, const Value &Val2, |
||
59 | const Environment &Env2) override; |
||
60 | |||
61 | bool merge(QualType Type, const Value &Val1, const Environment &Env1, |
||
62 | const Value &Val2, const Environment &Env2, Value &MergedVal, |
||
63 | Environment &MergedEnv) override; |
||
64 | |||
65 | Value *widen(QualType Type, Value &Prev, const Environment &PrevEnv, |
||
66 | Value &Current, Environment &CurrentEnv) override; |
||
67 | |||
68 | private: |
||
69 | CFGMatchSwitch<TransferState<NoopLattice>> TransferMatchSwitch; |
||
70 | }; |
||
71 | |||
72 | class UncheckedOptionalAccessDiagnoser { |
||
73 | public: |
||
74 | UncheckedOptionalAccessDiagnoser( |
||
75 | UncheckedOptionalAccessModelOptions Options = {}); |
||
76 | |||
77 | std::vector<SourceLocation> diagnose(ASTContext &Ctx, const CFGElement *Elt, |
||
78 | const Environment &Env); |
||
79 | |||
80 | private: |
||
81 | CFGMatchSwitch<const Environment, std::vector<SourceLocation>> |
||
82 | DiagnoseMatchSwitch; |
||
83 | }; |
||
84 | |||
85 | } // namespace dataflow |
||
86 | } // namespace clang |
||
87 | |||
88 | #endif // CLANG_ANALYSIS_FLOWSENSITIVE_MODELS_UNCHECKEDOPTIONALACCESSMODEL_H |