https://github.com/yuxuanchen1997 created 
https://github.com/llvm/llvm-project/pull/72346

This change aims to fix https://github.com/llvm/llvm-project/issues/70375

It appears to me that the logic here should be handling specializations in 
general. Not just partial specialization. It also seems that both the comment 
before the block and the `isInstantiationOf(ClassTemplate, SpecTemplate)` below 
agree with my judgement. 

The issue might just be a mistake that someone mistaken specialization as a 
special case of partial specializations, while it's actually the other way 
around.

Needs some experts to comment here if this is the right fix. 

The code that caused clang ICE is added as a test case. 

>From f238608b792f69b93eb445ee596125f3e20acf39 Mon Sep 17 00:00:00 2001
From: Yuxuan Chen <y...@meta.com>
Date: Tue, 14 Nov 2023 20:52:21 -0800
Subject: [PATCH 1/4] [Clang] Fix ICE caused by mishandling template
 specialization in instantiation lookup

---
 clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 011356e08a04297..2ef0986dd4d2235 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -6211,9 +6211,8 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, 
NamedDecl *D,
     ClassTemplateDecl *ClassTemplate = Record->getDescribedClassTemplate();
     if (ClassTemplate)
       ClassTemplate = ClassTemplate->getCanonicalDecl();
-    else if (ClassTemplatePartialSpecializationDecl *PartialSpec
-               = dyn_cast<ClassTemplatePartialSpecializationDecl>(Record))
-      ClassTemplate = 
PartialSpec->getSpecializedTemplate()->getCanonicalDecl();
+    else if (ClassTemplateSpecializationDecl *Spec = 
dyn_cast<ClassTemplateSpecializationDecl>(Record))
+      ClassTemplate = Spec->getSpecializedTemplate()->getCanonicalDecl();
 
     // Walk the current context to find either the record or an instantiation 
of
     // it.

>From 9a79db980951299c93cc4530230717af6f4668b3 Mon Sep 17 00:00:00 2001
From: Yuxuan Chen <y...@meta.com>
Date: Tue, 14 Nov 2023 20:55:10 -0800
Subject: [PATCH 2/4] formatting

---
 clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp 
b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 2ef0986dd4d2235..07b3488a21e670b 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -6211,7 +6211,8 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, 
NamedDecl *D,
     ClassTemplateDecl *ClassTemplate = Record->getDescribedClassTemplate();
     if (ClassTemplate)
       ClassTemplate = ClassTemplate->getCanonicalDecl();
-    else if (ClassTemplateSpecializationDecl *Spec = 
dyn_cast<ClassTemplateSpecializationDecl>(Record))
+    else if (ClassTemplateSpecializationDecl *Spec =
+                 dyn_cast<ClassTemplateSpecializationDecl>(Record))
       ClassTemplate = Spec->getSpecializedTemplate()->getCanonicalDecl();
 
     // Walk the current context to find either the record or an instantiation 
of

>From df884c7127bb2f0956521adc479a923c62220d7c Mon Sep 17 00:00:00 2001
From: Yuxuan Chen <y...@meta.com>
Date: Tue, 14 Nov 2023 21:04:00 -0800
Subject: [PATCH 3/4] Provide test case

---
 .../member-template-specialization.cpp        | 31 +++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 clang/test/SemaCXX/member-template-specialization.cpp

diff --git a/clang/test/SemaCXX/member-template-specialization.cpp 
b/clang/test/SemaCXX/member-template-specialization.cpp
new file mode 100644
index 000000000000000..baf5bd6ae7bb544
--- /dev/null
+++ b/clang/test/SemaCXX/member-template-specialization.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+// Verify that the inner template specialization can be found
+
+template <typename Ty>
+struct S {
+  static void bar() {
+    Ty t;
+    t.foo();
+  }
+
+  static void take(Ty&) {}
+};
+
+template <typename P>
+struct Outer {
+  template <typename C>
+  struct Inner;
+
+  using U = S<Inner<P>>;
+
+  template <>
+  struct Inner<void> {
+    void foo() {
+      U::take(*this);
+    }
+  };
+};
+
+int main() {
+  Outer<void>::U::bar();
+}

>From 7cdbce7944e051aed5b1f8ab789ce1e43f3e58b3 Mon Sep 17 00:00:00 2001
From: Yuxuan Chen <y...@meta.com>
Date: Tue, 14 Nov 2023 21:13:23 -0800
Subject: [PATCH 4/4] missing expected-no-diagnostics

---
 clang/test/SemaCXX/member-template-specialization.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang/test/SemaCXX/member-template-specialization.cpp 
b/clang/test/SemaCXX/member-template-specialization.cpp
index baf5bd6ae7bb544..29d46ec9c1e44fc 100644
--- a/clang/test/SemaCXX/member-template-specialization.cpp
+++ b/clang/test/SemaCXX/member-template-specialization.cpp
@@ -1,4 +1,6 @@
 // RUN: %clang_cc1 -verify -fsyntax-only %s
+// expected-no-diagnostics
+
 // Verify that the inner template specialization can be found
 
 template <typename Ty>

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to