1010
1111#include " absl/base/nullability.h"
1212#include " absl/log/check.h"
13- #include " nullability/pointer_nullability.h"
1413#include " nullability/type_nullability.h"
1514#include " clang/AST/Decl.h"
1615#include " clang/AST/DeclBase.h"
1716#include " clang/AST/Expr.h"
18- #include " clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
19- #include " clang/Analysis/FlowSensitive/DataflowEnvironment.h"
2017#include " clang/Analysis/FlowSensitive/DataflowLattice.h"
21- #include " clang/Analysis/FlowSensitive/StorageLocation.h"
22- #include " clang/Analysis/FlowSensitive/Value.h"
2318#include " clang/Basic/LLVM.h"
24- #include " llvm/ADT/DenseMap.h"
2519
2620namespace clang ::tidy::nullability {
2721namespace {
2822
2923using dataflow::LatticeJoinEffect;
30- using dataflow::PointerValue;
31- using dataflow::RecordStorageLocation;
32- using dataflow::StorageLocation;
33- using dataflow::Value;
3424
3525// Returns overridden nullability information associated with a declaration.
3626// For now we only track top-level decl nullability symbolically and check for
@@ -49,43 +39,10 @@ absl::Nullable<const PointerTypeNullability *> getDeclNullability(
4939 return nullptr ;
5040}
5141
52- template <typename T>
53- llvm::SmallDenseMap<const dataflow::RecordStorageLocation *,
54- llvm::SmallDenseMap<const FunctionDecl *, T *>>
55- joinConstMethodMap (
56- const llvm::SmallDenseMap<const dataflow::RecordStorageLocation *,
57- llvm::SmallDenseMap<const FunctionDecl *, T *>>
58- &Map1,
59- const llvm::SmallDenseMap<const dataflow::RecordStorageLocation *,
60- llvm::SmallDenseMap<const FunctionDecl *, T *>>
61- &Map2,
62- LatticeJoinEffect &Effect) {
63- llvm::SmallDenseMap<const dataflow::RecordStorageLocation *,
64- llvm::SmallDenseMap<const FunctionDecl *, T *>>
65- Result;
66- for (auto &[Loc, DeclToT] : Map1) {
67- auto It = Map2.find (Loc);
68- if (It == Map2.end ()) {
69- Effect = LatticeJoinEffect::Changed;
70- continue ;
71- }
72- const auto &OtherDeclToT = It->second ;
73- auto &JoinedDeclToT = Result[Loc];
74- for (auto [Func, Var] : DeclToT) {
75- T *OtherVar = OtherDeclToT.lookup (Func);
76- if (OtherVar == nullptr || OtherVar != Var) {
77- Effect = LatticeJoinEffect::Changed;
78- continue ;
79- }
80- JoinedDeclToT.insert ({Func, Var});
81- }
82- }
83- return Result;
84- }
85-
8642} // namespace
8743
88- const TypeNullability &PointerNullabilityLattice::insertExprNullabilityIfAbsent (
44+ const TypeNullability &
45+ PointerNullabilityLatticeBase::insertExprNullabilityIfAbsent (
8946 absl::Nonnull<const Expr *> E,
9047 const std::function<TypeNullability()> &GetNullability) {
9148 E = &dataflow::ignoreCFGOmittedNodes (*E);
@@ -100,41 +57,7 @@ const TypeNullability &PointerNullabilityLattice::insertExprNullabilityIfAbsent(
10057 return Iterator->second ;
10158}
10259
103- absl::Nullable<dataflow::Value *>
104- PointerNullabilityLattice::getConstMethodReturnValue (
105- const dataflow::RecordStorageLocation &RecordLoc,
106- absl::Nonnull<const CallExpr *> CE, dataflow::Environment &Env) {
107- assert (CE->getType ()->isPointerType () || CE->getType ()->isBooleanType ());
108- auto &ObjMap = ConstMethodReturnValues[&RecordLoc];
109- const FunctionDecl *DirectCallee = CE->getDirectCallee ();
110- if (DirectCallee == nullptr ) return nullptr ;
111- auto it = ObjMap.find (DirectCallee);
112- if (it != ObjMap.end ()) return it->second ;
113- dataflow::Value *Val = Env.createValue (CE->getType ());
114- if (Val != nullptr ) ObjMap.insert ({DirectCallee, Val});
115- return Val;
116- }
117-
118- absl::Nullable<dataflow::StorageLocation *>
119- PointerNullabilityLattice::getConstMethodReturnStorageLocation (
120- const dataflow::RecordStorageLocation &RecordLoc,
121- absl::Nonnull<const CallExpr *> CE, dataflow::Environment &Env) {
122- assert (isSupportedSmartPointerType (CE->getType ()));
123- auto &ObjMap = ConstMethodReturnStorageLocations[&RecordLoc];
124- const FunctionDecl *DirectCallee = CE->getDirectCallee ();
125- if (DirectCallee == nullptr ) return nullptr ;
126- auto it = ObjMap.find (DirectCallee);
127- if (it != ObjMap.end ()) return it->second ;
128- StorageLocation &Loc = Env.createStorageLocation (CE->getType ());
129- setSmartPointerValue (cast<RecordStorageLocation>(Loc),
130- cast<PointerValue>(Env.createValue (
131- underlyingRawPointerType (CE->getType ()))),
132- Env);
133- ObjMap.insert ({DirectCallee, &Loc});
134- return &Loc;
135- }
136-
137- void PointerNullabilityLattice::overrideNullabilityFromDecl (
60+ void PointerNullabilityLatticeBase::overrideNullabilityFromDecl (
13861 absl::Nullable<const Decl *> D, TypeNullability &N) const {
13962 // For now, overrides are always for pointer values only, and override only
14063 // the top-level nullability.
@@ -144,22 +67,9 @@ void PointerNullabilityLattice::overrideNullabilityFromDecl(
14467 }
14568}
14669
147- LatticeJoinEffect PointerNullabilityLattice::join (
148- const PointerNullabilityLattice &Other) {
149- // For simplicity, we only retain values that are identical, but not ones that
150- // are non-identical but equivalent. This is likely to be sufficient in
151- // practice, and it reduces implementation complexity considerably.
152-
153- LatticeJoinEffect Effect = LatticeJoinEffect::Unchanged;
154- ConstMethodReturnValues = joinConstMethodMap<Value>(
155- ConstMethodReturnValues, Other.ConstMethodReturnValues , Effect);
156- ;
157-
158- ConstMethodReturnStorageLocations = joinConstMethodMap<StorageLocation>(
159- ConstMethodReturnStorageLocations,
160- Other.ConstMethodReturnStorageLocations , Effect);
161-
162- return Effect;
70+ LatticeJoinEffect PointerNullabilityLatticeBase::join (
71+ const PointerNullabilityLatticeBase &Other) {
72+ return LatticeJoinEffect::Unchanged;
16373}
16474
16575} // namespace clang::tidy::nullability
0 commit comments