Annotate pointers in crubit/nullability Abseil nullability annotations.

PiperOrigin-RevId: 589849354
Change-Id: I741ec99392ad9e35870032df6f1d36e3986a7b23
diff --git a/nullability/BUILD b/nullability/BUILD
index 5c4e7af..e5f3721 100644
--- a/nullability/BUILD
+++ b/nullability/BUILD
@@ -12,6 +12,7 @@
     ],
     deps = [
         ":type_nullability",
+        "@absl//absl/base:nullability",
         "@absl//absl/container:flat_hash_map",
         "@absl//absl/log:check",
         "@llvm-project//clang:analysis",
@@ -62,6 +63,7 @@
         ":pointer_nullability_lattice",
         ":pointer_nullability_matchers",
         ":type_nullability",
+        "@absl//absl/base:nullability",
         "@absl//absl/log:check",
         "@llvm-project//clang:analysis",
         "@llvm-project//clang:ast",
@@ -77,13 +79,12 @@
     deps = [
         ":pointer_nullability",
         ":pointer_nullability_analysis",
-        ":pointer_nullability_lattice",
+        "@absl//absl/base:nullability",
         "@llvm-project//clang:analysis",
         "@llvm-project//clang:ast",
         "@llvm-project//clang:basic",
         "@llvm-project//clang:testing",
         "@llvm-project//llvm:Support",
-        "@llvm-project//third-party/unittest:gmock",
         "@llvm-project//third-party/unittest:gtest",
         "@llvm-project//third-party/unittest:gtest_main",
     ],
@@ -99,6 +100,7 @@
         ":pointer_nullability_lattice",
         ":pointer_nullability_matchers",
         ":type_nullability",
+        "@absl//absl/base:nullability",
         "@absl//absl/log:check",
         "@llvm-project//clang:analysis",
         "@llvm-project//clang:ast",
@@ -150,6 +152,7 @@
         "//nullability/test:__pkg__",
     ],
     deps = [
+        "@absl//absl/base:nullability",
         "@absl//absl/log:check",
         "@llvm-project//clang:analysis",
         "@llvm-project//clang:ast",
@@ -182,6 +185,7 @@
     visibility = [":__subpackages__"],
     deps = [
         "//third_party/protobuf",
+        "@absl//absl/base:nullability",
         "@llvm-project//llvm:Support",
         "@llvm-project//third-party/unittest:gmock",
     ],
@@ -195,6 +199,7 @@
         ":pointer_nullability_analysis",
         ":pointer_nullability_diagnosis",
         "//third_party/benchmark",
+        "@absl//absl/base:nullability",
         "@absl//absl/log:check",
         "@absl//absl/strings",
         "@absl//absl/strings:string_view",
diff --git a/nullability/inference/BUILD b/nullability/inference/BUILD
index f249345..452feea 100644
--- a/nullability/inference/BUILD
+++ b/nullability/inference/BUILD
@@ -16,6 +16,7 @@
         "//nullability:pointer_nullability_analysis",
         "//nullability:pointer_nullability_lattice",
         "//nullability:type_nullability",
+        "@absl//absl/base:nullability",
         "@absl//absl/container:flat_hash_map",
         "@absl//absl/log:check",
         "@llvm-project//clang:analysis",
@@ -191,6 +192,7 @@
     deps = [
         ":infer_tu",
         ":inference_cc_proto",
+        "@absl//absl/base:nullability",
         "@absl//absl/log:check",
         "@llvm-project//clang:ast",
         "@llvm-project//clang:basic",
diff --git a/nullability/inference/collect_evidence.cc b/nullability/inference/collect_evidence.cc
index 7c55917..212b1b2 100644
--- a/nullability/inference/collect_evidence.cc
+++ b/nullability/inference/collect_evidence.cc
@@ -11,6 +11,7 @@
 #include <utility>
 #include <vector>
 
+#include "absl/base/nullability.h"
 #include "absl/container/flat_hash_map.h"
 #include "absl/log/check.h"
 #include "nullability/inference/inferable.h"
@@ -242,7 +243,8 @@
 }
 
 auto getNullabilityAnnotationsFromTypeAndOverrides(
-    QualType Type, const Decl *D, const PointerNullabilityLattice &Lattice) {
+    QualType Type, absl::Nonnull<const Decl *> D,
+    const PointerNullabilityLattice &Lattice) {
   auto N = getNullabilityAnnotationsFromType(Type);
   if (N.empty()) {
     // We expect this not to be the case, but not to a crash-worthy level, so
@@ -788,7 +790,7 @@
     // We do want to see concrete code, including function instantiations.
     bool shouldVisitTemplateInstantiations() const { return true; }
 
-    bool VisitFunctionDecl(const FunctionDecl *FD) {
+    bool VisitFunctionDecl(absl::Nonnull<const FunctionDecl *> FD) {
       if (isInferenceTarget(*FD)) Out.Declarations.push_back(FD);
 
       // Visiting template instantiations is fine, these are valid functions!
diff --git a/nullability/inference/infer_tu_main.cc b/nullability/inference/infer_tu_main.cc
index 656d125..67c5ac2 100644
--- a/nullability/inference/infer_tu_main.cc
+++ b/nullability/inference/infer_tu_main.cc
@@ -14,6 +14,7 @@
 #include <string>
 #include <utility>
 
+#include "absl/base/nullability.h"
 #include "absl/log/check.h"
 #include "nullability/inference/infer_tu.h"
 #include "nullability/inference/inference.proto.h"
@@ -84,7 +85,8 @@
 // Walks the AST looking for declarations of symbols we inferred.
 // When it finds them, prints the inference as diagnostics.
 class DiagnosticPrinter : public RecursiveASTVisitor<DiagnosticPrinter> {
-  llvm::DenseMap<llvm::StringRef, const Inference *> InferenceByUSR;
+  llvm::DenseMap<llvm::StringRef, absl::Nonnull<const Inference *>>
+      InferenceByUSR;
   DiagnosticsEngine &Diags;
   unsigned DiagInferHere;
   unsigned DiagSample;
@@ -130,7 +132,7 @@
     DiagSample = Diags.getCustomDiagID(DiagnosticsEngine::Note, "%0 here");
   }
 
-  bool VisitDecl(const Decl *FD) {
+  bool VisitDecl(absl::Nonnull<const Decl *> FD) {
     llvm::SmallString<128> USR;
     if (!index::generateUSRForDecl(FD, USR))
       if (auto *I = InferenceByUSR.lookup(USR)) render(*I, FD->getLocation());
@@ -185,8 +187,8 @@
 };
 
 class Action : public SyntaxOnlyAction {
-  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &,
-                                                 llvm::StringRef) override {
+  absl::Nonnull<std::unique_ptr<ASTConsumer>> CreateASTConsumer(
+      CompilerInstance &, llvm::StringRef) override {
     class Consumer : public ASTConsumer {
       void HandleTranslationUnit(ASTContext &Ctx) override {
         llvm::errs() << "Running inference...\n";
@@ -212,7 +214,7 @@
 }  // namespace
 }  // namespace clang::tidy::nullability
 
-int main(int argc, const char **argv) {
+int main(int argc, absl::Nonnull<const char **> argv) {
   using namespace clang::tooling;
   auto Exec = createExecutorFromCommandLineArgs(argc, argv, Opts);
   QCHECK(Exec) << toString(Exec.takeError());
diff --git a/nullability/pointer_nullability.cc b/nullability/pointer_nullability.cc
index 93cac80..15ea94c 100644
--- a/nullability/pointer_nullability.cc
+++ b/nullability/pointer_nullability.cc
@@ -7,6 +7,7 @@
 #include <cassert>
 #include <optional>
 
+#include "absl/base/nullability.h"
 #include "nullability/type_nullability.h"
 #include "clang/AST/Type.h"
 #include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
@@ -40,8 +41,8 @@
   return Type->getNullability().value_or(NullabilityKind::Unspecified);
 }
 
-PointerValue *getPointerValueFromExpr(const Expr *PointerExpr,
-                                      const Environment &Env) {
+absl::Nullable<PointerValue *> getPointerValueFromExpr(
+    absl::Nonnull<const Expr *> PointerExpr, const Environment &Env) {
   return cast_or_null<PointerValue>(Env.getValue(*PointerExpr));
 }
 
@@ -88,10 +89,10 @@
   };
 }
 
-static bool tryCreatePointerNullState(PointerValue &PointerVal,
-                                      dataflow::Arena &A,
-                                      const Formula *FromNullable = nullptr,
-                                      const Formula *IsNull = nullptr) {
+static bool tryCreatePointerNullState(
+    PointerValue &PointerVal, dataflow::Arena &A,
+    absl::Nullable<const Formula *> FromNullable = nullptr,
+    absl::Nullable<const Formula *> IsNull = nullptr) {
   if (hasPointerNullState(PointerVal)) return false;
   if (!FromNullable) FromNullable = &A.makeAtomRef(A.makeAtom());
   if (!IsNull) IsNull = &A.makeAtomRef(A.makeAtom());
@@ -140,8 +141,9 @@
   return PointerVal;
 }
 
-bool isNullable(const PointerValue &PointerVal, const Environment &Env,
-                const dataflow::Formula *AdditionalConstraints) {
+bool isNullable(
+    const PointerValue &PointerVal, const Environment &Env,
+    absl::Nullable<const dataflow::Formula *> AdditionalConstraints) {
   auto &A = Env.getDataflowAnalysisContext().arena();
   auto [FromNullable, Null] = getPointerNullState(PointerVal);
 
@@ -159,9 +161,9 @@
   return Env.allows(*ForseeablyNull);
 }
 
-NullabilityKind getNullability(const dataflow::PointerValue &PointerVal,
-                               const dataflow::Environment &Env,
-                               const dataflow::Formula *AdditionalConstraints) {
+NullabilityKind getNullability(
+    const dataflow::PointerValue &PointerVal, const dataflow::Environment &Env,
+    absl::Nullable<const dataflow::Formula *> AdditionalConstraints) {
   auto &A = Env.getDataflowAnalysisContext().arena();
   if (auto *Null = getPointerNullState(PointerVal).IsNull) {
     if (AdditionalConstraints) Null = &A.makeAnd(*AdditionalConstraints, *Null);
diff --git a/nullability/pointer_nullability.h b/nullability/pointer_nullability.h
index f1c12ef..4032549 100644
--- a/nullability/pointer_nullability.h
+++ b/nullability/pointer_nullability.h
@@ -36,8 +36,8 @@
 
 /// Returns the `PointerValue` allocated to `PointerExpr` if available.
 /// Otherwise, returns nullptr.
-dataflow::PointerValue *getPointerValueFromExpr(
-    const Expr *PointerExpr, const dataflow::Environment &Env);
+absl::Nullable<dataflow::PointerValue *> getPointerValueFromExpr(
+    absl::Nonnull<const Expr *> PointerExpr, const dataflow::Environment &Env);
 
 /// Returns the `PointerValue` underlying a smart pointer, or null if no
 /// `PointerValue` is assigned to the smart pointer in the environment.
@@ -133,9 +133,9 @@
                                           dataflow::Environment &Env);
 
 /// Returns true if there is evidence that `PointerVal` may hold a nullptr.
-bool isNullable(const dataflow::PointerValue &PointerVal,
-                const dataflow::Environment &Env,
-                const dataflow::Formula *AdditionalConstraints = nullptr);
+bool isNullable(
+    const dataflow::PointerValue &PointerVal, const dataflow::Environment &Env,
+    absl::Nullable<const dataflow::Formula *> AdditionalConstraints = nullptr);
 
 /// Returns the strongest provable assertion we can make about `PointerVal`.
 /// If PointerVal may not be null, returns Nonnull.
@@ -143,13 +143,13 @@
 /// Otherwise, returns Unspecified.
 clang::NullabilityKind getNullability(
     const dataflow::PointerValue &PointerVal, const dataflow::Environment &Env,
-    const dataflow::Formula *AdditionalConstraints = nullptr);
+    absl::Nullable<const dataflow::Formula *> AdditionalConstraints = nullptr);
 
 /// Returns the strongest provable assertion we can make about the value of
 /// `E` in `Env`.
 clang::NullabilityKind getNullability(
-    const Expr *E, const dataflow::Environment &Env,
-    const dataflow::Formula *AdditionalConstraints = nullptr);
+    absl::Nonnull<const Expr *> E, const dataflow::Environment &Env,
+    absl::Nullable<const dataflow::Formula *> AdditionalConstraints = nullptr);
 
 // Work around the lack of Expr.dump() etc with an ostream but no ASTContext.
 template <typename T>
diff --git a/nullability/pointer_nullability_analysis.cc b/nullability/pointer_nullability_analysis.cc
index 85212c0..31bdedf 100644
--- a/nullability/pointer_nullability_analysis.cc
+++ b/nullability/pointer_nullability_analysis.cc
@@ -9,6 +9,7 @@
 #include <optional>
 #include <vector>
 
+#include "absl/base/nullability.h"
 #include "absl/log/check.h"
 #include "nullability/pointer_nullability.h"
 #include "nullability/pointer_nullability_lattice.h"
@@ -63,7 +64,7 @@
   return Result;
 }
 
-void computeNullability(const Expr *E,
+void computeNullability(absl::Nonnull<const Expr *> E,
                         TransferState<PointerNullabilityLattice> &State,
                         std::function<TypeNullability()> Compute) {
   (void)State.Lattice.insertExprNullabilityIfAbsent(E, [&] {
@@ -96,7 +97,8 @@
 // Returns the computed nullability for a subexpr of the current expression.
 // This is always available as we compute bottom-up.
 const TypeNullability &getNullabilityForChild(
-    const Expr *E, TransferState<PointerNullabilityLattice> &State) {
+    absl::Nonnull<const Expr *> E,
+    TransferState<PointerNullabilityLattice> &State) {
   return State.Lattice.insertExprNullabilityIfAbsent(E, [&] {
     // Since we process child nodes before parents, we should already have
     // computed the child nullability. However, this is not true in all test
@@ -214,7 +216,7 @@
 /// the given type after applying substitutions, which in this case is
 /// [_Nullable, _Nonnull].
 TypeNullability substituteNullabilityAnnotationsInFunctionTemplate(
-    QualType T, const CallExpr *CE) {
+    QualType T, absl::Nonnull<const CallExpr *> CE) {
   return getNullabilityAnnotationsFromType(
       T,
       [&](const SubstTemplateTypeParmType *ST)
@@ -254,7 +256,7 @@
 }
 
 PointerTypeNullability getPointerTypeNullability(
-    const Expr *E, PointerNullabilityAnalysis::Lattice &L) {
+    absl::Nonnull<const Expr *> E, PointerNullabilityAnalysis::Lattice &L) {
   // TODO: handle this in non-flow-sensitive transfer instead
   if (auto FromClang = E->getType()->getNullability();
       FromClang && *FromClang != NullabilityKind::Unspecified)
@@ -270,7 +272,7 @@
 }
 
 void initPointerFromTypeNullability(
-    PointerValue &PointerVal, const Expr *E,
+    PointerValue &PointerVal, absl::Nonnull<const Expr *> E,
     TransferState<PointerNullabilityLattice> &State) {
   initPointerNullState(PointerVal, State.Env.getDataflowAnalysisContext(),
                        getPointerTypeNullability(E, State.Lattice));
@@ -282,7 +284,8 @@
 /// TODO(mboehme): When we add support for smart pointers, this function will
 /// also need to be called when accessing the `PointerValue` that underlies the
 /// smart pointer.
-PointerValue *unpackPointerValue(PointerValue &PointerVal, Environment &Env) {
+absl::Nullable<PointerValue *> unpackPointerValue(PointerValue &PointerVal,
+                                                  Environment &Env) {
   auto [FromNullable, Null] = getPointerNullState(PointerVal);
   if (FromNullable && Null) return nullptr;
 
@@ -309,7 +312,7 @@
 }
 
 void transferValue_NullPointer(
-    const Expr *NullPointer, const MatchFinder::MatchResult &,
+    absl::Nonnull<const Expr *> NullPointer, const MatchFinder::MatchResult &,
     TransferState<PointerNullabilityLattice> &State) {
   if (auto *PointerVal = getPointerValueFromExpr(NullPointer, State.Env)) {
     initNullPointer(*PointerVal, State.Env.getDataflowAnalysisContext());
@@ -317,7 +320,8 @@
 }
 
 void transferValue_NotNullPointer(
-    const Expr *NotNullPointer, const MatchFinder::MatchResult &,
+    absl::Nonnull<const Expr *> NotNullPointer,
+    const MatchFinder::MatchResult &,
     TransferState<PointerNullabilityLattice> &State) {
   if (auto *PointerVal = getPointerValueFromExpr(NotNullPointer, State.Env)) {
     initPointerNullState(*PointerVal, State.Env.getDataflowAnalysisContext(),
@@ -527,7 +531,7 @@
   initPointerFromTypeNullability(*Val, PointerExpr, State);
 }
 
-void transferValue_Pointer(const Expr *PointerExpr,
+void transferValue_Pointer(absl::Nonnull<const Expr *> PointerExpr,
                            const MatchFinder::MatchResult &Result,
                            TransferState<PointerNullabilityLattice> &State) {
   auto *PointerVal = getPointerValueFromExpr(PointerExpr, State.Env);
@@ -550,7 +554,8 @@
 // unknown pointers when there is evidence that it is nullable, for example
 // when the pointer is compared to nullptr, or casted to boolean.
 void transferValue_NullCheckComparison(
-    const BinaryOperator *BinaryOp, const MatchFinder::MatchResult &result,
+    absl::Nonnull<const BinaryOperator *> BinaryOp,
+    const MatchFinder::MatchResult &result,
     TransferState<PointerNullabilityLattice> &State) {
   auto &A = State.Env.arena();
 
@@ -613,7 +618,7 @@
 }
 
 void transferValue_NullCheckImplicitCastPtrToBool(
-    const Expr *CastExpr, const MatchFinder::MatchResult &,
+    absl::Nonnull<const Expr *> CastExpr, const MatchFinder::MatchResult &,
     TransferState<PointerNullabilityLattice> &State) {
   auto &A = State.Env.arena();
   auto *PointerVal =
@@ -628,8 +633,8 @@
     State.Env.setValue(*CastExpr, A.makeTopValue());
 }
 
-void initializeOutputParameter(const Expr *Arg, dataflow::Environment &Env,
-                               QualType ParamTy) {
+void initializeOutputParameter(absl::Nonnull<const Expr *> Arg,
+                               dataflow::Environment &Env, QualType ParamTy) {
   // When a function has an "output parameter" - a non-const pointer or
   // reference to a pointer of unknown nullability - assume that the function
   // may set the pointer to non-null.
@@ -672,7 +677,7 @@
   Env.setValue(*Loc, *InnerPointer);
 }
 
-void transferValue_CallExpr(const CallExpr *CallExpr,
+void transferValue_CallExpr(absl::Nonnull<const CallExpr *> CallExpr,
                             const MatchFinder::MatchResult &Result,
                             TransferState<PointerNullabilityLattice> &State) {
   // The dataflow framework itself does not create values for `CallExpr`s.
@@ -727,7 +732,8 @@
 }
 
 void transferValue_AccessorCall(
-    const CXXMemberCallExpr *MCE, const MatchFinder::MatchResult &Result,
+    absl::Nonnull<const CXXMemberCallExpr *> MCE,
+    const MatchFinder::MatchResult &Result,
     TransferState<PointerNullabilityLattice> &State) {
   auto *member = Result.Nodes.getNodeAs<clang::ValueDecl>("member-decl");
   PointerValue *PointerVal = nullptr;
@@ -748,7 +754,8 @@
 }
 
 void transferValue_ConstMemberCall(
-    const CXXMemberCallExpr *MCE, const MatchFinder::MatchResult &Result,
+    absl::Nonnull<const CXXMemberCallExpr *> MCE,
+    const MatchFinder::MatchResult &Result,
     TransferState<PointerNullabilityLattice> &State) {
   if (!isSupportedRawPointerType(MCE->getType()) || !MCE->isPRValue()) {
     // We can't handle it as a special case, but still need to handle it.
@@ -771,7 +778,8 @@
 }
 
 void transferValue_NonConstMemberCall(
-    const CXXMemberCallExpr *MCE, const MatchFinder::MatchResult &Result,
+    absl::Nonnull<const CXXMemberCallExpr *> MCE,
+    const MatchFinder::MatchResult &Result,
     TransferState<PointerNullabilityLattice> &State) {
   // When a non-const member function is called, reset all pointer-type fields
   // of the implicit object.
@@ -788,7 +796,7 @@
   transferValue_CallExpr(MCE, Result, State);
 }
 
-void transferType_DeclRefExpr(const DeclRefExpr *DRE,
+void transferType_DeclRefExpr(absl::Nonnull<const DeclRefExpr *> DRE,
                               const MatchFinder::MatchResult &MR,
                               TransferState<PointerNullabilityLattice> &State) {
   computeNullability(DRE, State, [&] {
@@ -798,7 +806,7 @@
   });
 }
 
-void transferType_MemberExpr(const MemberExpr *ME,
+void transferType_MemberExpr(absl::Nonnull<const MemberExpr *> ME,
                              const MatchFinder::MatchResult &MR,
                              TransferState<PointerNullabilityLattice> &State) {
   computeNullability(ME, State, [&]() {
@@ -822,7 +830,8 @@
 }
 
 void transferType_MemberCallExpr(
-    const CXXMemberCallExpr *MCE, const MatchFinder::MatchResult &MR,
+    absl::Nonnull<const CXXMemberCallExpr *> MCE,
+    const MatchFinder::MatchResult &MR,
     TransferState<PointerNullabilityLattice> &State) {
   computeNullability(MCE, State, [&]() {
     return ArrayRef(getNullabilityForChild(MCE->getCallee(), State))
@@ -831,7 +840,7 @@
   });
 }
 
-void transferType_CastExpr(const CastExpr *CE,
+void transferType_CastExpr(absl::Nonnull<const CastExpr *> CE,
                            const MatchFinder::MatchResult &MR,
                            TransferState<PointerNullabilityLattice> &State) {
   computeNullability(CE, State, [&]() -> TypeNullability {
@@ -972,7 +981,8 @@
 }
 
 void transferType_MaterializeTemporaryExpr(
-    const MaterializeTemporaryExpr *MTE, const MatchFinder::MatchResult &MR,
+    absl::Nonnull<const MaterializeTemporaryExpr *> MTE,
+    const MatchFinder::MatchResult &MR,
     TransferState<PointerNullabilityLattice> &State) {
   computeNullability(MTE, State, [&]() {
     return getNullabilityForChild(MTE->getSubExpr(), State);
@@ -987,7 +997,7 @@
   });
 }
 
-void transferType_CallExpr(const CallExpr *CE,
+void transferType_CallExpr(absl::Nonnull<const CallExpr *> CE,
                            const MatchFinder::MatchResult &MR,
                            TransferState<PointerNullabilityLattice> &State) {
   // TODO: Check CallExpr arguments in the diagnoser against the nullability of
@@ -1007,7 +1017,7 @@
 }
 
 void transferType_UnaryOperator(
-    const UnaryOperator *UO, const MatchFinder::MatchResult &MR,
+    absl::Nonnull<const UnaryOperator *> UO, const MatchFinder::MatchResult &MR,
     TransferState<PointerNullabilityLattice> &State) {
   computeNullability(UO, State, [&]() -> TypeNullability {
     switch (UO->getOpcode()) {
@@ -1039,7 +1049,7 @@
   });
 }
 
-void transferType_NewExpr(const CXXNewExpr *NE,
+void transferType_NewExpr(absl::Nonnull<const CXXNewExpr *> NE,
                           const MatchFinder::MatchResult &MR,
                           TransferState<PointerNullabilityLattice> &State) {
   computeNullability(NE, State, [&]() {
@@ -1051,7 +1061,8 @@
 }
 
 void transferType_ArraySubscriptExpr(
-    const ArraySubscriptExpr *ASE, const MatchFinder::MatchResult &MR,
+    absl::Nonnull<const ArraySubscriptExpr *> ASE,
+    const MatchFinder::MatchResult &MR,
     TransferState<PointerNullabilityLattice> &State) {
   computeNullability(ASE, State, [&]() {
     auto &BaseNullability = getNullabilityForChild(ASE->getBase(), State);
@@ -1063,7 +1074,7 @@
   });
 }
 
-void transferType_ThisExpr(const CXXThisExpr *TE,
+void transferType_ThisExpr(absl::Nonnull<const CXXThisExpr *> TE,
                            const MatchFinder::MatchResult &MR,
                            TransferState<PointerNullabilityLattice> &State) {
   computeNullability(TE, State, [&]() {
@@ -1184,7 +1195,7 @@
 }
 
 PointerTypeNullability PointerNullabilityAnalysis::assignNullabilityVariable(
-    const ValueDecl *D, dataflow::Arena &A) {
+    absl::Nonnull<const ValueDecl *> D, dataflow::Arena &A) {
   auto [It, Inserted] = NFS.DeclTopLevelNullability.try_emplace(D);
   if (Inserted) It->second = PointerTypeNullability::createSymbolic(A);
   return It->second;
@@ -1200,11 +1211,10 @@
   ValueTransferer(Elt, getASTContext(), State);
 }
 
-static const Formula *mergeFormulas(const Formula *Bool1,
-                                    const Environment &Env1,
-                                    const Formula *Bool2,
-                                    const Environment &Env2,
-                                    Environment &MergedEnv) {
+static absl::Nullable<const Formula *> mergeFormulas(
+    absl::Nullable<const Formula *> Bool1, const Environment &Env1,
+    absl::Nullable<const Formula *> Bool2, const Environment &Env2,
+    Environment &MergedEnv) {
   if (Bool1 == Bool2) {
     return Bool1;
   }
@@ -1321,10 +1331,9 @@
 // returns `Cur`, as this is the formula that is appropriate to use in the
 // current environment (where we will produce the widened pointer). Otherwise,
 // returns null, to indicate that the property should be widened to "top".
-static const Formula *widenNullabilityProperty(const Formula *Prev,
-                                               const Environment &PrevEnv,
-                                               const Formula *Cur,
-                                               Environment &CurEnv) {
+static absl::Nullable<const Formula *> widenNullabilityProperty(
+    absl::Nullable<const Formula *> Prev, const Environment &PrevEnv,
+    absl::Nullable<const Formula *> Cur, Environment &CurEnv) {
   if (Prev == Cur) return Cur;
   if (Prev == nullptr || Cur == nullptr) return nullptr;
 
@@ -1340,10 +1349,9 @@
   return nullptr;
 }
 
-Value *PointerNullabilityAnalysis::widen(QualType Type, Value &Prev,
-                                         const Environment &PrevEnv,
-                                         Value &Current,
-                                         Environment &CurrentEnv) {
+absl::Nullable<Value *> PointerNullabilityAnalysis::widen(
+    QualType Type, Value &Prev, const Environment &PrevEnv, Value &Current,
+    Environment &CurrentEnv) {
   // Widen pointers to a pointer with a "top" storage location.
   if (auto *PrevPtr = dyn_cast<PointerValue>(&Prev)) {
     auto &CurPtr = cast<PointerValue>(Current);
diff --git a/nullability/pointer_nullability_analysis.h b/nullability/pointer_nullability_analysis.h
index bdf9358..9275397 100644
--- a/nullability/pointer_nullability_analysis.h
+++ b/nullability/pointer_nullability_analysis.h
@@ -8,6 +8,7 @@
 #include <optional>
 #include <utility>
 
+#include "absl/base/nullability.h"
 #include "nullability/pointer_nullability_lattice.h"
 #include "nullability/type_nullability.h"
 #include "clang/AST/ASTContext.h"
@@ -67,8 +68,8 @@
   // variables are only associated with direct reads of pointer values from D.
   //
   // The returned nullability is guaranteed to be symbolic.
-  PointerTypeNullability assignNullabilityVariable(const ValueDecl *D,
-                                                   dataflow::Arena &);
+  PointerTypeNullability assignNullabilityVariable(
+      absl::Nonnull<const ValueDecl *> D, dataflow::Arena &);
 
   void assignNullabilityOverride(
       llvm::unique_function<
@@ -90,10 +91,10 @@
       const dataflow::Environment &Env1, const dataflow::Value &Val2,
       const dataflow::Environment &Env2) override;
 
-  dataflow::Value *widen(QualType Type, dataflow::Value &Prev,
-                         const dataflow::Environment &PrevEnv,
-                         dataflow::Value &Current,
-                         dataflow::Environment &CurrentEnv) override;
+  absl::Nullable<dataflow::Value *> widen(
+      QualType Type, dataflow::Value &Prev,
+      const dataflow::Environment &PrevEnv, dataflow::Value &Current,
+      dataflow::Environment &CurrentEnv) override;
 
  private:
   // Returns a storage location representing "top", i.e. a storage location of
diff --git a/nullability/pointer_nullability_analysis_benchmark.cc b/nullability/pointer_nullability_analysis_benchmark.cc
index eba9461..7e1de00 100644
--- a/nullability/pointer_nullability_analysis_benchmark.cc
+++ b/nullability/pointer_nullability_analysis_benchmark.cc
@@ -4,6 +4,7 @@
 
 #include <cstdint>
 
+#include "absl/base/nullability.h"
 #include "absl/log/check.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/string_view.h"
@@ -20,7 +21,8 @@
 namespace clang::tidy::nullability {
 namespace {
 
-NamedDecl *lookup(absl::string_view Name, const DeclContext &DC) {
+absl::Nonnull<NamedDecl *> lookup(absl::string_view Name,
+                                  const DeclContext &DC) {
   auto Result = DC.lookup(&DC.getParentASTContext().Idents.get(Name));
   CHECK(Result.isSingleResult()) << Name;
   return Result.front();
@@ -222,7 +224,7 @@
 }  // namespace
 }  // namespace clang::tidy::nullability
 
-int main(int argc, char **argv) {
+int main(int argc, absl::Nonnull<char **> argv) {
   benchmark::Initialize(&argc, argv);
   benchmark::RunSpecifiedBenchmarks();
   return 0;
diff --git a/nullability/pointer_nullability_analysis_test.cc b/nullability/pointer_nullability_analysis_test.cc
index 9c3d846..fa0011f 100644
--- a/nullability/pointer_nullability_analysis_test.cc
+++ b/nullability/pointer_nullability_analysis_test.cc
@@ -8,6 +8,7 @@
 #include <optional>
 #include <utility>
 
+#include "absl/base/nullability.h"
 #include "nullability/pointer_nullability.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
@@ -26,7 +27,7 @@
 namespace clang::tidy::nullability {
 namespace {
 
-NamedDecl *lookup(StringRef Name, const DeclContext &DC) {
+absl::Nonnull<NamedDecl *> lookup(StringRef Name, const DeclContext &DC) {
   auto Result = DC.lookup(&DC.getParentASTContext().Idents.get(Name));
   EXPECT_TRUE(Result.isSingleResult()) << Name;
   return Result.front();
diff --git a/nullability/pointer_nullability_diagnosis.cc b/nullability/pointer_nullability_diagnosis.cc
index c9b6b2e..b089f05 100644
--- a/nullability/pointer_nullability_diagnosis.cc
+++ b/nullability/pointer_nullability_diagnosis.cc
@@ -6,6 +6,7 @@
 
 #include <optional>
 
+#include "absl/base/nullability.h"
 #include "absl/log/check.h"
 #include "nullability/pointer_nullability.h"
 #include "nullability/pointer_nullability_matchers.h"
@@ -40,7 +41,7 @@
 
 // Diagnoses whether `E` violates the expectation that it is nonnull.
 SmallVector<PointerNullabilityDiagnostic> diagnoseNonnullExpected(
-    const Expr *E, const Environment &Env,
+    absl::Nonnull<const Expr *> E, const Environment &Env,
     PointerNullabilityDiagnostic::Context DiagCtx,
     std::optional<std::string> ParamName = std::nullopt) {
   if (auto *ActualVal = getPointerValueFromExpr(E, Env)) {
@@ -66,8 +67,9 @@
 // Diagnoses whether the nullability of `E` is incompatible with the expectation
 // set by `DeclaredType`.
 SmallVector<PointerNullabilityDiagnostic> diagnoseTypeExprCompatibility(
-    QualType DeclaredType, const Expr *E, const Environment &Env,
-    ASTContext &Ctx, PointerNullabilityDiagnostic::Context DiagCtx,
+    QualType DeclaredType, absl::Nonnull<const Expr *> E,
+    const Environment &Env, ASTContext &Ctx,
+    PointerNullabilityDiagnostic::Context DiagCtx,
     std::optional<std::string> ParamName = std::nullopt) {
   CHECK(isSupportedRawPointerType(DeclaredType));
   return getNullabilityKind(DeclaredType, Ctx) == NullabilityKind::NonNull
@@ -76,7 +78,8 @@
 }
 
 SmallVector<PointerNullabilityDiagnostic> diagnoseDereference(
-    const UnaryOperator *UnaryOp, const MatchFinder::MatchResult &,
+    absl::Nonnull<const UnaryOperator *> UnaryOp,
+    const MatchFinder::MatchResult &,
     const TransferStateForDiagnostics<PointerNullabilityLattice> &State) {
   return diagnoseNonnullExpected(
       UnaryOp->getSubExpr(), State.Env,
@@ -84,7 +87,8 @@
 }
 
 SmallVector<PointerNullabilityDiagnostic> diagnoseArrow(
-    const MemberExpr *MemberExpr, const MatchFinder::MatchResult &Result,
+    absl::Nonnull<const MemberExpr *> MemberExpr,
+    const MatchFinder::MatchResult &Result,
     const TransferStateForDiagnostics<PointerNullabilityLattice> &State) {
   return diagnoseNonnullExpected(
       MemberExpr->getBase(), State.Env,
@@ -161,7 +165,7 @@
 ///    }
 /// \endcode
 SmallVector<PointerNullabilityDiagnostic> diagnoseAssertNullabilityCall(
-    const CallExpr *CE,
+    absl::Nonnull<const CallExpr *> CE,
     const TransferStateForDiagnostics<PointerNullabilityLattice> &State,
     ASTContext &Ctx) {
   auto *DRE = cast<DeclRefExpr>(CE->getCallee()->IgnoreImpCasts());
@@ -207,7 +211,7 @@
 }
 
 SmallVector<PointerNullabilityDiagnostic> diagnoseCallExpr(
-    const CallExpr *CE, const MatchFinder::MatchResult &Result,
+    absl::Nonnull<const CallExpr *> CE, const MatchFinder::MatchResult &Result,
     const TransferStateForDiagnostics<PointerNullabilityLattice> &State) {
   // Check whether the callee is null.
   // - Skip direct callees to avoid handling builtin functions, which don't
@@ -270,7 +274,8 @@
 }
 
 SmallVector<PointerNullabilityDiagnostic> diagnoseConstructExpr(
-    const CXXConstructExpr *CE, const MatchFinder::MatchResult &Result,
+    absl::Nonnull<const CXXConstructExpr *> CE,
+    const MatchFinder::MatchResult &Result,
     const TransferStateForDiagnostics<PointerNullabilityLattice> &State) {
   auto *CalleeFPT = CE->getConstructor()->getType()->getAs<FunctionProtoType>();
   if (!CalleeFPT) return {};
@@ -283,7 +288,8 @@
 }
 
 SmallVector<PointerNullabilityDiagnostic> diagnoseReturn(
-    const ReturnStmt *RS, const MatchFinder::MatchResult &Result,
+    absl::Nonnull<const ReturnStmt *> RS,
+    const MatchFinder::MatchResult &Result,
     const TransferStateForDiagnostics<PointerNullabilityLattice> &State) {
   auto ReturnType = cast<FunctionDecl>(State.Env.getDeclCtx())->getReturnType();
 
@@ -301,7 +307,8 @@
 }
 
 SmallVector<PointerNullabilityDiagnostic> diagnoseMemberInitializer(
-    const CXXCtorInitializer *CI, const MatchFinder::MatchResult &Result,
+    absl::Nonnull<const CXXCtorInitializer *> CI,
+    const MatchFinder::MatchResult &Result,
     const TransferStateForDiagnostics<PointerNullabilityLattice> &State) {
   CHECK(CI->isAnyMemberInitializer());
   auto MemberType = CI->getAnyMember()->getType();
diff --git a/nullability/pointer_nullability_lattice.cc b/nullability/pointer_nullability_lattice.cc
index abab6ab..e2d0c03 100644
--- a/nullability/pointer_nullability_lattice.cc
+++ b/nullability/pointer_nullability_lattice.cc
@@ -6,6 +6,7 @@
 
 #include <optional>
 
+#include "absl/base/nullability.h"
 #include "absl/log/check.h"
 #include "nullability/type_nullability.h"
 #include "clang/AST/Decl.h"
@@ -17,8 +18,8 @@
 // Returns overridden nullability information associated with a declaration.
 // For now we only track top-level decl nullability symbolically and check for
 // concrete nullability override results.
-const PointerTypeNullability *getDeclNullability(
-    const Decl *D,
+absl::Nullable<const PointerTypeNullability *> getDeclNullability(
+    absl::Nullable<const Decl *> D,
     const PointerNullabilityLattice::NonFlowSensitiveState &NFS) {
   if (!D) return nullptr;
   if (const auto *VD = dyn_cast_or_null<ValueDecl>(D)) {
@@ -33,7 +34,7 @@
 }  // namespace
 
 void PointerNullabilityLattice::overrideNullabilityFromDecl(
-    const Decl *D, TypeNullability &N) const {
+    absl::Nullable<const Decl *> D, TypeNullability &N) const {
   // For now, overrides are always for pointer values only, and override only
   // the top-level nullability.
   if (auto *PN = getDeclNullability(D, NFS)) {
diff --git a/nullability/pointer_nullability_lattice.h b/nullability/pointer_nullability_lattice.h
index 6457ca5..898e55f 100644
--- a/nullability/pointer_nullability_lattice.h
+++ b/nullability/pointer_nullability_lattice.h
@@ -9,6 +9,7 @@
 #include <optional>
 #include <ostream>
 
+#include "absl/base/nullability.h"
 #include "absl/container/flat_hash_map.h"
 #include "absl/log/check.h"
 #include "nullability/type_nullability.h"
@@ -31,7 +32,8 @@
     // These are set by PointerNullabilityAnalysis::assignNullabilityVariable,
     // and take precedence over the declared type and over any result from
     // ConcreteNullabilityOverride.
-    absl::flat_hash_map<const ValueDecl *, PointerTypeNullability>
+    absl::flat_hash_map<absl::Nonnull<const ValueDecl *>,
+                        PointerTypeNullability>
         DeclTopLevelNullability;
     // Returns overriding concrete nullability for decls. This is set by
     // PointerNullabilityAnalysis::assignNullabilityOverride, and the result, if
@@ -43,7 +45,8 @@
 
   PointerNullabilityLattice(NonFlowSensitiveState &NFS) : NFS(NFS) {}
 
-  const TypeNullability *getExprNullability(const Expr *E) const {
+  absl::Nullable<const TypeNullability *> getExprNullability(
+      absl::Nonnull<const Expr *> E) const {
     auto I = NFS.ExprToNullability.find(&dataflow::ignoreCFGOmittedNodes(*E));
     return I == NFS.ExprToNullability.end() ? nullptr : &I->second;
   }
@@ -53,7 +56,8 @@
   // the provided GetNullability.
   // Returns the (cached or computed) nullability.
   const TypeNullability &insertExprNullabilityIfAbsent(
-      const Expr *E, const std::function<TypeNullability()> &GetNullability) {
+      absl::Nonnull<const Expr *> E,
+      const std::function<TypeNullability()> &GetNullability) {
     E = &dataflow::ignoreCFGOmittedNodes(*E);
     if (auto It = NFS.ExprToNullability.find(E);
         It != NFS.ExprToNullability.end())
@@ -69,9 +73,10 @@
   // Gets the PointerValue associated with the RecordStorageLocation and
   // MethodDecl of the CallExpr, creating one if it doesn't yet exist. Requires
   // the CXXMemberCallExpr to have a supported pointer type.
-  dataflow::PointerValue *getConstMethodReturnValue(
+  absl::Nonnull<dataflow::PointerValue *> getConstMethodReturnValue(
       const dataflow::RecordStorageLocation &RecordLoc,
-      const CXXMemberCallExpr *MCE, dataflow::Environment &Env) {
+      absl::Nonnull<const CXXMemberCallExpr *> MCE,
+      dataflow::Environment &Env) {
     auto &ObjMap = ConstMethodReturnValues[&RecordLoc];
     auto it = ObjMap.find(MCE->getMethodDecl());
     if (it != ObjMap.end()) return it->second;
@@ -87,7 +92,8 @@
 
   // If nullability for the decl D has been overridden, patch N to reflect it.
   // (N is the nullability of an access to D).
-  void overrideNullabilityFromDecl(const Decl *D, TypeNullability &N) const;
+  void overrideNullabilityFromDecl(absl::Nullable<const Decl *> D,
+                                   TypeNullability &N) const;
 
   bool operator==(const PointerNullabilityLattice &Other) const { return true; }
 
diff --git a/nullability/proto_matchers.cc b/nullability/proto_matchers.cc
index 87f02fd..5059958 100644
--- a/nullability/proto_matchers.cc
+++ b/nullability/proto_matchers.cc
@@ -8,6 +8,7 @@
 #include <ostream>
 #include <string>
 
+#include "absl/base/nullability.h"
 #include "llvm/ADT/StringRef.h"
 #include "third_party/llvm/llvm-project/third-party/unittest/googlemock/include/gmock/gmock.h"
 #include "third_party/protobuf/message.h"
@@ -23,8 +24,9 @@
  public:
   EqualsProtoMatcher(llvm::StringRef Expected) : Expected(Expected) {}
 
-  bool MatchAndExplain(const proto2::Message &M,
-                       testing::MatchResultListener *Listener) const override {
+  bool MatchAndExplain(
+      const proto2::Message &M,
+      absl::Nonnull<testing::MatchResultListener *> Listener) const override {
     std::unique_ptr<proto2::Message> Parsed(M.New());
     if (!proto2::TextFormat::ParseFromString(Expected, Parsed.get())) {
       *Listener << "where <<<\n"
@@ -45,7 +47,7 @@
                                        Listener);
   }
 
-  void DescribeTo(std::ostream *OS) const override {
+  void DescribeTo(absl::Nonnull<std::ostream *> OS) const override {
     *OS << "equals proto <<<\n" << Expected << "\n>>>";
   }
 };
diff --git a/nullability/type_nullability.cc b/nullability/type_nullability.cc
index 0d6447a..132ddc7 100644
--- a/nullability/type_nullability.cc
+++ b/nullability/type_nullability.cc
@@ -9,6 +9,7 @@
 #include <utility>
 #include <vector>
 
+#include "absl/base/nullability.h"
 #include "absl/log/check.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTFwd.h"
@@ -299,7 +300,7 @@
     if (TA.getKind() == TemplateArgument::Pack)
       for (const auto &PackElt : TA.getPackAsArray()) Visit(PackElt);
   }
-  void Visit(const DeclContext *DC) {
+  void Visit(absl::Nonnull<const DeclContext *> DC) {
     // For now, only consider enclosing classes.
     // TODO: The nullability of template functions can affect local classes too,
     // this can be relevant e.g. when instantiating templates with such types.
@@ -307,7 +308,7 @@
       Visit(DC->getParentASTContext().getRecordType(CRD));
   }
 
-  void VisitType(const Type *T) {
+  void VisitType(absl::Nonnull<const Type *> T) {
     // For sugar not explicitly handled below, desugar and continue.
     // (We need to walk the full structure of the canonical type.)
     if (auto *Desugar =
@@ -321,13 +322,14 @@
     Base::VisitType(T);
   }
 
-  void VisitFunctionProtoType(const FunctionProtoType *FPT) {
+  void VisitFunctionProtoType(absl::Nonnull<const FunctionProtoType *> FPT) {
     ignoreUnexpectedNullability();
     Visit(FPT->getReturnType());
     for (auto ParamType : FPT->getParamTypes()) Visit(ParamType);
   }
 
-  void VisitTemplateSpecializationType(const TemplateSpecializationType *TST) {
+  void VisitTemplateSpecializationType(
+      absl::Nonnull<const TemplateSpecializationType *> TST) {
     if (TST->isTypeAlias()) {
       if (auto NK = getAliasNullability(TST->getTemplateName()))
         sawNullability(*NK);
@@ -372,7 +374,8 @@
     }
   }
 
-  void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
+  void VisitSubstTemplateTypeParmType(
+      absl::Nonnull<const SubstTemplateTypeParmType *> T) {
     // The underlying type of T in the AST has no sugar, as the template has
     // only one body instantiated per canonical args.
     // Instead, try to find the (sugared) template argument that T is bound to.
@@ -410,7 +413,7 @@
   }
 
   // If we see foo<args>::ty then we may need sugar from args to resugar ty.
-  void VisitElaboratedType(const ElaboratedType *ET) {
+  void VisitElaboratedType(absl::Nonnull<const ElaboratedType *> ET) {
     std::vector<TemplateContext> BoundTemplateArgs;
     // Iterate over qualifiers right-to-left, looking for template args.
     for (auto *NNS = ET->getQualifier(); NNS; NNS = NNS->getPrefix()) {
@@ -445,7 +448,7 @@
     Visit(ET->getNamedType());
   }
 
-  void VisitRecordType(const RecordType *RT) {
+  void VisitRecordType(absl::Nonnull<const RecordType *> RT) {
     if (isSupportedSmartPointerType(QualType(RT, 0))) {
       derived().report(
           RT, PendingNullability.value_or(NullabilityKind::Unspecified));
@@ -461,7 +464,7 @@
     }
   }
 
-  void VisitAttributedType(const AttributedType *AT) {
+  void VisitAttributedType(absl::Nonnull<const AttributedType *> AT) {
     if (auto NK = AT->getImmediateNullability()) sawNullability(*NK);
     Visit(AT->getModifiedType());
     CHECK(!PendingNullability.has_value())
@@ -469,50 +472,55 @@
         << AT->getModifiedType().getAsString();
   }
 
-  void VisitPointerType(const PointerType *PT) {
+  void VisitPointerType(absl::Nonnull<const PointerType *> PT) {
     derived().report(PT,
                      PendingNullability.value_or(NullabilityKind::Unspecified));
     PendingNullability.reset();
     Visit(PT->getPointeeType());
   }
 
-  void VisitReferenceType(const ReferenceType *RT) {
+  void VisitReferenceType(absl::Nonnull<const ReferenceType *> RT) {
     ignoreUnexpectedNullability();
     Visit(RT->getPointeeTypeAsWritten());
   }
 
-  void VisitArrayType(const ArrayType *AT) {
+  void VisitArrayType(absl::Nonnull<const ArrayType *> AT) {
     ignoreUnexpectedNullability();
     Visit(AT->getElementType());
   }
 };
 
-template <typename T>
-unsigned countPointers(const T &Object) {
-  struct Walker : public NullabilityWalker<Walker> {
-    unsigned Count = 0;
-    void report(const Type *, NullabilityKind) { ++Count; }
-  } PointerCountWalker;
-  PointerCountWalker.Visit(Object);
+struct CountWalker : public NullabilityWalker<CountWalker> {
+  unsigned Count = 0;
+  void report(absl::Nonnull<const Type *>, NullabilityKind) { ++Count; }
+};
+}  // namespace
+
+unsigned countPointersInType(QualType T) {
+  CountWalker PointerCountWalker;
+  PointerCountWalker.Visit(T);
   return PointerCountWalker.Count;
 }
 
-}  // namespace
-
-unsigned countPointersInType(QualType T) { return countPointers(T); }
-
-unsigned countPointersInType(const DeclContext *DC) {
-  return countPointers(DC);
+unsigned countPointersInType(absl::Nonnull<const DeclContext *> DC) {
+  CountWalker PointerCountWalker;
+  PointerCountWalker.Visit(DC);
+  return PointerCountWalker.Count;
 }
-unsigned countPointersInType(TemplateArgument TA) { return countPointers(TA); }
 
-QualType exprType(const Expr *E) {
+unsigned countPointersInType(const TemplateArgument &TA) {
+  CountWalker PointerCountWalker;
+  PointerCountWalker.Visit(TA);
+  return PointerCountWalker.Count;
+}
+
+QualType exprType(absl::Nonnull<const Expr *> E) {
   if (E->hasPlaceholderType(BuiltinType::BoundMember))
     return Expr::findBoundMemberType(E);
   return E->getType();
 }
 
-unsigned countPointersInType(const Expr *E) {
+unsigned countPointersInType(absl::Nonnull<const Expr *> E) {
   return countPointersInType(exprType(E));
 }
 
@@ -520,13 +528,17 @@
     QualType T,
     llvm::function_ref<GetTypeParamNullability> SubstituteTypeParam) {
   CHECK(!T->isDependentType()) << T.getAsString();
+
   struct Walker : NullabilityWalker<Walker> {
     std::vector<PointerTypeNullability> Annotations;
     llvm::function_ref<GetTypeParamNullability> SubstituteTypeParam;
 
-    void report(const Type *, NullabilityKind NK) { Annotations.push_back(NK); }
+    void report(absl::Nonnull<const Type *>, NullabilityKind NK) {
+      Annotations.push_back(NK);
+    }
 
-    void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *ST) {
+    void VisitSubstTemplateTypeParmType(
+        absl::Nonnull<const SubstTemplateTypeParmType *> ST) {
       if (SubstituteTypeParam) {
         if (auto Subst = SubstituteTypeParam(ST)) {
           DCHECK_EQ(Subst->size(),
@@ -540,12 +552,13 @@
       NullabilityWalker::VisitSubstTemplateTypeParmType(ST);
     }
   } AnnotationVisitor;
+
   AnnotationVisitor.SubstituteTypeParam = SubstituteTypeParam;
   AnnotationVisitor.Visit(T);
   return std::move(AnnotationVisitor.Annotations);
 }
 
-TypeNullability unspecifiedNullability(const Expr *E) {
+TypeNullability unspecifiedNullability(absl::Nonnull<const Expr *> E) {
   return TypeNullability(countPointersInType(E), NullabilityKind::Unspecified);
 }
 
@@ -582,9 +595,9 @@
   }
 
   // Default behavior for unhandled types: do not transform.
-  QualType VisitType(const Type *T) { return QualType(T, 0); }
+  QualType VisitType(absl::Nonnull<const Type *> T) { return QualType(T, 0); }
 
-  QualType VisitPointerType(const PointerType *PT) {
+  QualType VisitPointerType(absl::Nonnull<const PointerType *> PT) {
     CHECK(!Nullability.empty())
         << "Nullability vector too short at " << QualType(PT, 0).getAsString();
     NullabilityKind NK = Nullability.front().concrete();
@@ -596,7 +609,7 @@
                                  Rebuilt, Rebuilt);
   }
 
-  QualType VisitRecordType(const RecordType *RT) {
+  QualType VisitRecordType(absl::Nonnull<const RecordType *> RT) {
     if (const auto *CTSD =
             dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl())) {
       std::vector<TemplateArgument> TransformedArgs;
@@ -609,31 +622,34 @@
     return QualType(RT, 0);
   }
 
-  QualType VisitFunctionProtoType(const FunctionProtoType *T) {
+  QualType VisitFunctionProtoType(absl::Nonnull<const FunctionProtoType *> T) {
     QualType Ret = Visit(T->getReturnType());
     std::vector<QualType> Params;
     for (const auto &Param : T->getParamTypes()) Params.push_back(Visit(Param));
     return Ctx.getFunctionType(Ret, Params, T->getExtProtoInfo());
   }
 
-  QualType VisitLValueReferenceType(const LValueReferenceType *T) {
+  QualType VisitLValueReferenceType(
+      absl::Nonnull<const LValueReferenceType *> T) {
     return Ctx.getLValueReferenceType(Visit(T->getPointeeType()));
   }
-  QualType VisitRValueReferenceType(const RValueReferenceType *T) {
+  QualType VisitRValueReferenceType(
+      absl::Nonnull<const RValueReferenceType *> T) {
     return Ctx.getRValueReferenceType(Visit(T->getPointeeType()));
   }
 
-  QualType VisitConstantArrayType(const ConstantArrayType *AT) {
+  QualType VisitConstantArrayType(absl::Nonnull<const ConstantArrayType *> AT) {
     return Ctx.getConstantArrayType(Visit(AT->getElementType()), AT->getSize(),
                                     AT->getSizeExpr(), AT->getSizeModifier(),
                                     AT->getIndexTypeCVRQualifiers());
   }
-  QualType VisitIncompleteArrayType(const IncompleteArrayType *AT) {
+  QualType VisitIncompleteArrayType(
+      absl::Nonnull<const IncompleteArrayType *> AT) {
     return Ctx.getIncompleteArrayType(Visit(AT->getElementType()),
                                       AT->getSizeModifier(),
                                       AT->getIndexTypeCVRQualifiers());
   }
-  QualType VisitVariableArrayType(const VariableArrayType *AT) {
+  QualType VisitVariableArrayType(absl::Nonnull<const VariableArrayType *> AT) {
     return Ctx.getVariableArrayType(
         Visit(AT->getElementType()), AT->getSizeExpr(), AT->getSizeModifier(),
         AT->getIndexTypeCVRQualifiers(), AT->getBracketsRange());
diff --git a/nullability/type_nullability.h b/nullability/type_nullability.h
index bbd8421..3eac9e7 100644
--- a/nullability/type_nullability.h
+++ b/nullability/type_nullability.h
@@ -30,6 +30,7 @@
 #include <tuple>
 #include <vector>
 
+#include "absl/base/nullability.h"
 #include "absl/log/check.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Expr.h"
@@ -191,15 +192,15 @@
 /// Each of these could conceptually be nullable, so this is the length of
 /// the nullability vector computed by getNullabilityAnnotationsFromType().
 unsigned countPointersInType(QualType T);
-unsigned countPointersInType(const Expr *E);
-unsigned countPointersInType(TemplateArgument TA);
-unsigned countPointersInType(const DeclContext *DC);
+unsigned countPointersInType(absl::Nonnull<const Expr *> E);
+unsigned countPointersInType(const TemplateArgument &TA);
+unsigned countPointersInType(absl::Nonnull<const DeclContext *> DC);
 
 /// Returns the type of an expression for the purposes of nullability.
 /// This handles wrinkles in the type system like BoundMember.
-QualType exprType(const Expr *E);
+QualType exprType(absl::Nonnull<const Expr *> E);
 
-TypeNullability unspecifiedNullability(const Expr *E);
+TypeNullability unspecifiedNullability(absl::Nonnull<const Expr *> E);
 
 }  // namespace clang::tidy::nullability