Author: Matheus Izvekov Date: 2026-05-27T14:09:30Z New Revision: f56774213bf4da41882a468ef8b9f4b44a52ec1d
URL: https://github.com/llvm/llvm-project/commit/f56774213bf4da41882a468ef8b9f4b44a52ec1d DIFF: https://github.com/llvm/llvm-project/commit/f56774213bf4da41882a468ef8b9f4b44a52ec1d.diff LOG: [clang] fix finding class template instantiation pattern for member specializations (#199979) Stop treating the member which a member specialization specializes as the pattern of the former. Split off from https://github.com/llvm/llvm-project/pull/199528 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/AST/DeclCXX.cpp clang/test/CXX/temp/temp.spec/temp.expl.spec/p7.cpp clang/test/Modules/cxx-templates.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index f3865672120e0..4fe64e88e7ff2 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -675,6 +675,7 @@ Bug Fixes to C++ Support - Fixed a crash when diagnosing an invalid static member function with an explicit object parameter (#GH177741) - Clang incorrectly instantiated variable specializations outside of the immediate context. (#GH54439) - Fixed a crash when pack expansions are used as arguments for non-pack parameters of built-in templates. (#GH180307) +- Fixed crash instantiating class member specializations. - Fix a problem where a substitution failure when evaluating a type requirement could directly make the program ill-formed. - Fix a problem where pack index expressions where incorrectly being regarded as equivalent. diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 2a58313b699e2..2de8ba8f484f4 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -2088,20 +2088,23 @@ const CXXRecordDecl *CXXRecordDecl::getTemplateInstantiationPattern() const { if (auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(this)) { auto From = TD->getInstantiatedFrom(); if (auto *CTD = dyn_cast_if_present<ClassTemplateDecl *>(From)) { - while (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate()) { - if (NewCTD->isMemberSpecialization()) + while (!CTD->isMemberSpecialization()) { + ClassTemplateDecl *D = CTD->getInstantiatedFromMemberTemplate(); + if (!D) break; - CTD = NewCTD; + CTD = D; } return CTD->getTemplatedDecl(); } if (auto *CTPSD = dyn_cast_if_present<ClassTemplatePartialSpecializationDecl *>( From)) { - while (auto *NewCTPSD = CTPSD->getInstantiatedFromMember()) { - if (NewCTPSD->isMemberSpecialization()) + while (!CTPSD->isMemberSpecialization()) { + ClassTemplatePartialSpecializationDecl *D = + CTPSD->getInstantiatedFromMember(); + if (!D) break; - CTPSD = NewCTPSD; + CTPSD = D; } return CTPSD; } diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p7.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p7.cpp index b93562a60de57..af07024cb7af5 100644 --- a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p7.cpp +++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p7.cpp @@ -83,11 +83,8 @@ namespace Undefined { static_assert(A<short>::f<int>() == 1); static_assert(A<short>::x<int> == 1); static_assert(A<short>::x<int*> == 2); -#if 0 - // FIXME: crashes static_assert(A<short>::B<int>::y == 1); static_assert(A<short>::B<int*>::y == 2); -#endif } // namespace Undefined namespace Defined { @@ -337,8 +334,5 @@ namespace Dependent { static_assert(A<0>::f<2>() == 2); static_assert(A<0>::x<2> == 2); -#if 0 - // FIXME: crashes static_assert(A<0>::B<2>::y == 2); -#endif } // namespace Dependent diff --git a/clang/test/Modules/cxx-templates.cpp b/clang/test/Modules/cxx-templates.cpp index 15f6091774424..e36511d8e315f 100644 --- a/clang/test/Modules/cxx-templates.cpp +++ b/clang/test/Modules/cxx-templates.cpp @@ -193,8 +193,7 @@ namespace hidden_specializations { cls<char*> uk4; // expected-error 1+{{partial specialization of 'cls<T *>' must be imported}} expected-error 1+{{definition of}} cls<void>::nested_cls unk1; // expected-error 1+{{explicit specialization of 'nested_cls' must be imported}} expected-error 1+{{definition of}} cls<void>::nested_cls_t<int> unk2; // expected-error 1+{{explicit specialization of 'nested_cls_t' must be imported}} expected-error 1+{{definition of}} - // [email protected]:29 {{explicit specialization of 'nested_cls_t' must be imported}} - // expected-note@-2 {{in evaluation of exception specification}} + // expected-error@+1 1+{{definition of 'nested_cls_t' must be imported}} cls<void>::nested_cls_t<char> unk3; // expected-error 1+{{explicit specialization of 'nested_cls_t' must be imported}} // For enums, uses that would trigger instantiations of definitions are not _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
