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