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 |