[nullability] Fix crash on function template calls that only deduce some arguments.

PiperOrigin-RevId: 527531959
diff --git a/nullability_verification/pointer_nullability_analysis.cc b/nullability_verification/pointer_nullability_analysis.cc
index e4a4729..946fa11 100644
--- a/nullability_verification/pointer_nullability_analysis.cc
+++ b/nullability_verification/pointer_nullability_analysis.cc
@@ -173,7 +173,18 @@
         if (auto* DRE =
                 dyn_cast<DeclRefExpr>(CE->getCallee()->IgnoreImpCasts());
             DRE != nullptr && ST->getReplacedParameter()->getDepth() == 0 &&
-            DRE->hasExplicitTemplateArgs()) {
+            // Some or all of the template arguments may be deduced, and we
+            // won't see those on the `DeclRefExpr`. If the template argument
+            // was deduced, we don't have any sugar for it.
+            // TODO: Can we somehow obtain it from the function param it was
+            // deduced from?
+            // TODO: This check, as well as the index into `template_arguments`
+            // below, may be incorrect in the presence of parameters packs.
+            // In function templates, parameter packs may appear anywhere in the
+            // parameter list. The index may therefore refer to one of the
+            // pack arguments, but we might incorrectly interpret it as
+            // referring to an argument that follows the pack.
+            ST->getIndex() < DRE->template_arguments().size()) {
           TypeSourceInfo* TSI =
               DRE->template_arguments()[ST->getIndex()].getTypeSourceInfo();
           if (TSI == nullptr) return std::nullopt;
diff --git a/nullability_verification/test/function_calls.cc b/nullability_verification/test/function_calls.cc
index effa853..e64a6da 100644
--- a/nullability_verification/test/function_calls.cc
+++ b/nullability_verification/test/function_calls.cc
@@ -435,6 +435,14 @@
   )cc"));
 }
 
+TEST(PointerNullabilityTest, CallFunctionTemplate_PartiallyDeduced) {
+  EXPECT_TRUE(checkDiagnostics(R"cc(
+    template <int, class T>
+    T f(T);
+    void target() { f<0>(1); }
+  )cc"));
+}
+
 }  // namespace
 }  // namespace nullability
 }  // namespace tidy