Internal change

PiperOrigin-RevId: 544335572
Change-Id: I28e98c4973519b8c0da29e5f8bc51078cffb52ce
diff --git a/nullability/pointer_nullability_analysis.cc b/nullability/pointer_nullability_analysis.cc
index 3964d1c..b950422 100644
--- a/nullability/pointer_nullability_analysis.cc
+++ b/nullability/pointer_nullability_analysis.cc
@@ -15,6 +15,7 @@
 #include "nullability/type_nullability.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTDumper.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/OperationKinds.h"
 #include "clang/AST/Stmt.h"
@@ -137,6 +138,12 @@
         // (e.g. PointerNullabilityTest.MemberFunctionTemplateOfTemplateStruct)
         if (!Specialization || Specialization != ST->getAssociatedDecl())
           return std::nullopt;
+        // TODO: The code below does not deal correctly with partial
+        // specializations. We should eventually handle these, but for now, just
+        // bail out.
+        if (isa<ClassTemplatePartialSpecializationDecl>(
+                ST->getReplacedParameter()->getDeclContext()))
+          return std::nullopt;
 
         unsigned ArgIndex = ST->getIndex();
         auto TemplateArgs = Specialization->getTemplateArgs().asArray();
diff --git a/nullability/test/templates.cc b/nullability/test/templates.cc
index 00357f5..37fa7b8 100644
--- a/nullability/test/templates.cc
+++ b/nullability/test/templates.cc
@@ -1189,5 +1189,24 @@
   )cc"));
 }
 
+TEST(PointerNullabilityTest, MethodOnPartialSpecialization) {
+  EXPECT_TRUE(checkDiagnostics(R"cc(
+    template <class T>
+    struct S {};
+    template <class T1, class T2>
+    struct pair {};
+    template <class T1, class T2>
+    struct S<pair<T1, T2>> {
+      T1 Foo(T1, T2);
+    };
+    void target(int* _Nonnull p1, char* _Nullable p2) {
+      S<pair<int* _Nonnull, char* _Nullable>> s;
+      // TODO: Should be NK_nonnull, but we don't treat partial specializations
+      // correctly yet.
+      __assert_nullability<NK_unspecified>(s.Foo(p1, p2));
+    }
+  )cc"));
+}
+
 }  // namespace
 }  // namespace clang::tidy::nullability