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

via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 20 16:11:15 PST 2023


Author: Yuxuan Chen
Date: 2023-11-20T16:11:11-08:00
New Revision: d3285123bc9c2e170c8aa7e418c132119bc7aaf1

URL: https://github.com/llvm/llvm-project/commit/d3285123bc9c2e170c8aa7e418c132119bc7aaf1
DIFF: https://github.com/llvm/llvm-project/commit/d3285123bc9c2e170c8aa7e418c132119bc7aaf1.diff

LOG: [Clang] Fix finding instantiated decls for class template specializations during instantiation (#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.

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
    clang/test/SemaCXX/template-specialization.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 324dd3410beb5d2..93ec15a7f095961 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -608,6 +608,8 @@ Bug Fixes in This Version
 
 - Fixed an issue that a benign assertion might hit when instantiating a pack expansion
   inside a lambda. (`#61460 <https://github.com/llvm/llvm-project/issues/61460>`_)
+- Fix crash during instantiation of some class template specializations within class
+  templates. Fixes (`#70375 <https://github.com/llvm/llvm-project/issues/70375>`_)
 
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 011356e08a04297..08f4ba00fc9f7de 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -6207,13 +6207,13 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
       return D;
 
     // Determine whether this record is the "templated" declaration describing
-    // a class template or class template partial specialization.
+    // a class template or class template specialization.
     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/template-specialization.cpp b/clang/test/SemaCXX/template-specialization.cpp
index ae7bc332fccee1d..7b26ff9f5c5ba49 100644
--- a/clang/test/SemaCXX/template-specialization.cpp
+++ b/clang/test/SemaCXX/template-specialization.cpp
@@ -19,3 +19,36 @@ int main() {
   B::foo<4>(); // expected-note {{in instantiation of function template specialization 'B::foo<4>'}}
   return 0;
 }
+
+namespace GH70375 {
+
+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);
+    }
+  };
+};
+
+void instantiate() {
+  Outer<void>::U::bar();
+}
+
+}


        


More information about the cfe-commits mailing list