Dani Ferreira Franco Moura | 3d56a22 | 2022-11-29 03:12:55 -0800 | [diff] [blame] | 1 | // Part of the Crubit project, under the Apache License v2.0 with LLVM |
| 2 | // Exceptions. See /LICENSE for license information. |
| 3 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 4 | |
Sam McCall | da39880 | 2023-06-27 01:57:22 -0700 | [diff] [blame] | 5 | #ifndef CRUBIT_NULLABILITY_POINTER_NULLABILITY_LATTICE_H_ |
| 6 | #define CRUBIT_NULLABILITY_POINTER_NULLABILITY_LATTICE_H_ |
Dani Ferreira Franco Moura | 3d56a22 | 2022-11-29 03:12:55 -0800 | [diff] [blame] | 7 | |
Dmitri Gribenko | 742c4c3 | 2023-07-31 12:32:09 -0700 | [diff] [blame] | 8 | #include <functional> |
Dani Ferreira Franco Moura | 3d56a22 | 2022-11-29 03:12:55 -0800 | [diff] [blame] | 9 | #include <ostream> |
| 10 | |
Dani Ferreira Franco Moura | 97f5c61 | 2022-12-17 13:28:24 -0800 | [diff] [blame] | 11 | #include "absl/container/flat_hash_map.h" |
Googler | d443731 | 2023-01-17 15:10:29 -0800 | [diff] [blame] | 12 | #include "absl/log/check.h" |
Sam McCall | d127f93 | 2023-05-02 07:15:27 -0700 | [diff] [blame] | 13 | #include "nullability/type_nullability.h" |
Sam McCall | 74bf864 | 2023-06-16 11:21:42 -0700 | [diff] [blame] | 14 | #include "clang/AST/Expr.h" |
Dani Ferreira Franco Moura | 0d0db1d | 2023-01-17 11:08:07 -0800 | [diff] [blame] | 15 | #include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h" |
Dani Ferreira Franco Moura | 3d56a22 | 2022-11-29 03:12:55 -0800 | [diff] [blame] | 16 | #include "clang/Analysis/FlowSensitive/DataflowLattice.h" |
| 17 | |
Sam McCall | 4f6be42 | 2023-06-27 02:51:22 -0700 | [diff] [blame] | 18 | namespace clang::tidy::nullability { |
Dani Ferreira Franco Moura | 3d56a22 | 2022-11-29 03:12:55 -0800 | [diff] [blame] | 19 | |
| 20 | class PointerNullabilityLattice { |
| 21 | public: |
Sam McCall | 74bf864 | 2023-06-16 11:21:42 -0700 | [diff] [blame] | 22 | struct NonFlowSensitiveState { |
| 23 | absl::flat_hash_map<const Expr *, TypeNullability> ExprToNullability; |
| 24 | // Overridden symbolic nullability for pointer-typed decls. |
Sam McCall | e644e1d | 2023-07-18 19:19:12 -0700 | [diff] [blame] | 25 | // These are set by PointerNullabilityAnalysis::assignNullabilityVariable, |
| 26 | // and take precedence over the declared type. |
Sam McCall | 74bf864 | 2023-06-16 11:21:42 -0700 | [diff] [blame] | 27 | absl::flat_hash_map<const ValueDecl *, PointerTypeNullability> |
| 28 | DeclTopLevelNullability; |
| 29 | }; |
| 30 | |
| 31 | PointerNullabilityLattice(NonFlowSensitiveState &NFS) : NFS(NFS) {} |
Dani Ferreira Franco Moura | 97f5c61 | 2022-12-17 13:28:24 -0800 | [diff] [blame] | 32 | |
Sam McCall | d127f93 | 2023-05-02 07:15:27 -0700 | [diff] [blame] | 33 | const TypeNullability *getExprNullability(const Expr *E) const { |
Sam McCall | 74bf864 | 2023-06-16 11:21:42 -0700 | [diff] [blame] | 34 | auto I = NFS.ExprToNullability.find(&dataflow::ignoreCFGOmittedNodes(*E)); |
| 35 | return I == NFS.ExprToNullability.end() ? nullptr : &I->second; |
Dani Ferreira Franco Moura | 97f5c61 | 2022-12-17 13:28:24 -0800 | [diff] [blame] | 36 | } |
| 37 | |
| 38 | // If the `ExprToNullability` map already contains an entry for `E`, does |
| 39 | // nothing. Otherwise, inserts a new entry with key `E` and value computed by |
| 40 | // the provided GetNullability. |
Googler | d443731 | 2023-01-17 15:10:29 -0800 | [diff] [blame] | 41 | // Returns the (cached or computed) nullability. |
Sam McCall | d127f93 | 2023-05-02 07:15:27 -0700 | [diff] [blame] | 42 | const TypeNullability &insertExprNullabilityIfAbsent( |
| 43 | const Expr *E, const std::function<TypeNullability()> &GetNullability) { |
Googler | d443731 | 2023-01-17 15:10:29 -0800 | [diff] [blame] | 44 | E = &dataflow::ignoreCFGOmittedNodes(*E); |
Sam McCall | 74bf864 | 2023-06-16 11:21:42 -0700 | [diff] [blame] | 45 | if (auto It = NFS.ExprToNullability.find(E); |
| 46 | It != NFS.ExprToNullability.end()) |
Googler | d443731 | 2023-01-17 15:10:29 -0800 | [diff] [blame] | 47 | return It->second; |
| 48 | // Deliberately perform a separate lookup after calling GetNullability. |
| 49 | // It may invalidate iterators, e.g. inserting missing vectors for children. |
Sam McCall | 74bf864 | 2023-06-16 11:21:42 -0700 | [diff] [blame] | 50 | auto [Iterator, Inserted] = |
| 51 | NFS.ExprToNullability.insert({E, GetNullability()}); |
Googler | d443731 | 2023-01-17 15:10:29 -0800 | [diff] [blame] | 52 | CHECK(Inserted) << "GetNullability inserted same " << E->getStmtClassName(); |
| 53 | return Iterator->second; |
Dani Ferreira Franco Moura | 97f5c61 | 2022-12-17 13:28:24 -0800 | [diff] [blame] | 54 | } |
| 55 | |
Sam McCall | 74bf864 | 2023-06-16 11:21:42 -0700 | [diff] [blame] | 56 | // Returns overridden nullability information associated with a declaration. |
| 57 | // For now we only track top-level decl nullability symbolically. |
| 58 | const PointerTypeNullability *getDeclNullability(const ValueDecl *D) const { |
| 59 | auto It = NFS.DeclTopLevelNullability.find(D); |
| 60 | if (It == NFS.DeclTopLevelNullability.end()) return nullptr; |
| 61 | return &It->second; |
| 62 | } |
| 63 | |
Dani Ferreira Franco Moura | 3d56a22 | 2022-11-29 03:12:55 -0800 | [diff] [blame] | 64 | bool operator==(const PointerNullabilityLattice &Other) const { return true; } |
| 65 | |
| 66 | dataflow::LatticeJoinEffect join(const PointerNullabilityLattice &Other) { |
| 67 | return dataflow::LatticeJoinEffect::Unchanged; |
| 68 | } |
Sam McCall | 74bf864 | 2023-06-16 11:21:42 -0700 | [diff] [blame] | 69 | |
| 70 | private: |
| 71 | // Owned by the PointerNullabilityAnalysis object, shared by all lattice |
| 72 | // elements within one analysis run. |
| 73 | NonFlowSensitiveState &NFS; |
Dani Ferreira Franco Moura | 3d56a22 | 2022-11-29 03:12:55 -0800 | [diff] [blame] | 74 | }; |
| 75 | |
| 76 | inline std::ostream &operator<<(std::ostream &OS, |
| 77 | const PointerNullabilityLattice &) { |
| 78 | return OS << "noop"; |
| 79 | } |
| 80 | |
Sam McCall | 4f6be42 | 2023-06-27 02:51:22 -0700 | [diff] [blame] | 81 | } // namespace clang::tidy::nullability |
Dani Ferreira Franco Moura | 3d56a22 | 2022-11-29 03:12:55 -0800 | [diff] [blame] | 82 | |
Sam McCall | da39880 | 2023-06-27 01:57:22 -0700 | [diff] [blame] | 83 | #endif // CRUBIT_NULLABILITY_POINTER_NULLABILITY_LATTICE_H_ |