[clang] [Clang] Fix finding instantiated decls for class template specializations during instantiation (PR #72346)

via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 14 21:17:12 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Yuxuan Chen (yuxuanchen1997)

<details>
<summary>Changes</summary>

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. 

---
Full diff: https://github.com/llvm/llvm-project/pull/72346.diff


2 Files Affected:

- (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+3-3) 
- (added) clang/test/SemaCXX/member-template-specialization.cpp (+33) 


``````````diff
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 011356e08a04297..07b3488a21e670b 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -6211,9 +6211,9 @@ 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.
diff --git a/clang/test/SemaCXX/member-template-specialization.cpp b/clang/test/SemaCXX/member-template-specialization.cpp
new file mode 100644
index 000000000000000..29d46ec9c1e44fc
--- /dev/null
+++ b/clang/test/SemaCXX/member-template-specialization.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+// expected-no-diagnostics
+
+// 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();
+}

``````````

</details>


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


More information about the cfe-commits mailing list