This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG9dd2af0b4cae: Fix CRTP partial specialization instantiation 
crash. (authored by erichkeane).
Herald added a project: clang.

Changed prior to commit:
  https://reviews.llvm.org/D150285?vs=521049&id=521283#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D150285/new/

https://reviews.llvm.org/D150285

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/test/SemaTemplate/partial-spec-instantiate.cpp


Index: clang/test/SemaTemplate/partial-spec-instantiate.cpp
===================================================================
--- clang/test/SemaTemplate/partial-spec-instantiate.cpp
+++ clang/test/SemaTemplate/partial-spec-instantiate.cpp
@@ -134,3 +134,23 @@
 
   _Static_assert(S::value, "");
 }
+
+namespace GH60778 {
+  template <bool B = false> class ClassTemplate {
+  public:
+      template <typename T, typename = void> class Nested {};
+  };
+
+  template <typename DerivedType> class Base {};
+
+  template <>
+  template <typename T>
+  class ClassTemplate<>::Nested<T> : public Base<ClassTemplate<>::Nested<T> > 
{};
+
+  void use() {
+    // This should instantiate the body of Nested with the template arguments
+    // from the Partial Specialization. This would previously get confused and
+    // get the template arguments from the primary template instead.
+    ClassTemplate<>::Nested<int> instantiation;
+  }
+}
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -163,6 +163,14 @@
     assert(ClassTemplSpec->getSpecializedTemplate() && "No class template?");
     if (ClassTemplSpec->getSpecializedTemplate()->isMemberSpecialization())
       return Response::Done();
+
+    // If this was instantiated from a partial template specialization, we need
+    // to get the next level of declaration context from the partial
+    // specialization, as the ClassTemplateSpecializationDecl's
+    // DeclContext/LexicalDeclContext will be for the primary template.
+    if (auto *InstFromPartialTempl = 
ClassTemplSpec->getSpecializedTemplateOrPartial()
+                      .dyn_cast<ClassTemplatePartialSpecializationDecl *>())
+      return 
Response::ChangeDecl(InstFromPartialTempl->getLexicalDeclContext());
   }
   return Response::UseNextDecl(ClassTemplSpec);
 }
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -391,6 +391,10 @@
   at the point where it is required. This fixes:
   (`#62224 <https://github.com/llvm/llvm-project/issues/62224>`_) and
   (`#62596 <https://github.com/llvm/llvm-project/issues/62596>`_)
+- Fix an assertion when instantiating the body of a Class Template 
Specialization
+  when it had been instantiated from a partial template specialization with 
different
+  template arguments on the containing class. This fixes:
+  (`#60778 <https://github.com/llvm/llvm-project/issues/60778>`_).
 
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


Index: clang/test/SemaTemplate/partial-spec-instantiate.cpp
===================================================================
--- clang/test/SemaTemplate/partial-spec-instantiate.cpp
+++ clang/test/SemaTemplate/partial-spec-instantiate.cpp
@@ -134,3 +134,23 @@
 
   _Static_assert(S::value, "");
 }
+
+namespace GH60778 {
+  template <bool B = false> class ClassTemplate {
+  public:
+      template <typename T, typename = void> class Nested {};
+  };
+
+  template <typename DerivedType> class Base {};
+
+  template <>
+  template <typename T>
+  class ClassTemplate<>::Nested<T> : public Base<ClassTemplate<>::Nested<T> > {};
+
+  void use() {
+    // This should instantiate the body of Nested with the template arguments
+    // from the Partial Specialization. This would previously get confused and
+    // get the template arguments from the primary template instead.
+    ClassTemplate<>::Nested<int> instantiation;
+  }
+}
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -163,6 +163,14 @@
     assert(ClassTemplSpec->getSpecializedTemplate() && "No class template?");
     if (ClassTemplSpec->getSpecializedTemplate()->isMemberSpecialization())
       return Response::Done();
+
+    // If this was instantiated from a partial template specialization, we need
+    // to get the next level of declaration context from the partial
+    // specialization, as the ClassTemplateSpecializationDecl's
+    // DeclContext/LexicalDeclContext will be for the primary template.
+    if (auto *InstFromPartialTempl = ClassTemplSpec->getSpecializedTemplateOrPartial()
+                      .dyn_cast<ClassTemplatePartialSpecializationDecl *>())
+      return Response::ChangeDecl(InstFromPartialTempl->getLexicalDeclContext());
   }
   return Response::UseNextDecl(ClassTemplSpec);
 }
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -391,6 +391,10 @@
   at the point where it is required. This fixes:
   (`#62224 <https://github.com/llvm/llvm-project/issues/62224>`_) and
   (`#62596 <https://github.com/llvm/llvm-project/issues/62596>`_)
+- Fix an assertion when instantiating the body of a Class Template Specialization
+  when it had been instantiated from a partial template specialization with different
+  template arguments on the containing class. This fixes:
+  (`#60778 <https://github.com/llvm/llvm-project/issues/60778>`_).
 
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D150285: Fi... Erich Keane via Phabricator via cfe-commits
    • [PATCH] D15028... Alexander Shaposhnikov via Phabricator via cfe-commits
    • [PATCH] D15028... Erich Keane via Phabricator via cfe-commits

Reply via email to