[nullability] Improve treatment of function pointers:

- A function-to-pointer decay produces a non-null pointer
- Calling an unchecked nullable function pointer should produce a diagnostic
- When retrieving nullability annotations from a function type, also take
  nullability annotations in function parameters into account

PiperOrigin-RevId: 526871626
diff --git a/nullability_verification/pointer_nullability_analysis.cc b/nullability_verification/pointer_nullability_analysis.cc
index 3f83d02..8ec1323 100644
--- a/nullability_verification/pointer_nullability_analysis.cc
+++ b/nullability_verification/pointer_nullability_analysis.cc
@@ -19,6 +19,7 @@
 #include "clang/AST/Stmt.h"
 #include "clang/AST/Type.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
 #include "clang/Analysis/FlowSensitive/CFGMatchSwitch.h"
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
 #include "clang/Analysis/FlowSensitive/Value.h"
@@ -171,7 +172,7 @@
         // TODO: Handle nested templates (...->getDepth() > 0).
         if (auto* DRE =
                 dyn_cast<DeclRefExpr>(CE->getCallee()->IgnoreImpCasts());
-            ST->getReplacedParameter()->getDepth() == 0 &&
+            DRE != nullptr && ST->getReplacedParameter()->getDepth() == 0 &&
             DRE->hasExplicitTemplateArgs()) {
           return getNullabilityAnnotationsFromType(
               DRE->template_arguments()[ST->getIndex()]
@@ -366,7 +367,9 @@
     const CXXMemberCallExpr* MCE, const MatchFinder::MatchResult& MR,
     TransferState<PointerNullabilityLattice>& State) {
   computeNullability(MCE, State, [&]() {
-    return getNullabilityForChild(MCE->getCallee(), State).vec();
+    return getNullabilityForChild(MCE->getCallee(), State)
+        .take_front(countPointersInType(MCE))
+        .vec();
   });
 }
 
@@ -517,6 +520,9 @@
   // TODO: Check CallExpr arguments in the diagnoser against the nullability of
   // parameters.
   computeNullability(CE, State, [&]() {
+    // TODO(mboehme): Instead of relying on Clang to propagate nullability sugar
+    // to the `CallExpr`'s type, we should extract nullability directly from the
+    // callee `Expr .
     return substituteNullabilityAnnotationsInFunctionTemplate(CE->getType(),
                                                               CE);
   });