Author: Podchishchaeva, Mariya Date: 2023-07-24T09:36:58-07:00 New Revision: dcb8911316bec81f4f52b40cf0de789f1839730b
URL: https://github.com/llvm/llvm-project/commit/dcb8911316bec81f4f52b40cf0de789f1839730b DIFF: https://github.com/llvm/llvm-project/commit/dcb8911316bec81f4f52b40cf0de789f1839730b.diff LOG: [clang] Fix specialization of non-templated member classes of class templates Explicit specialization doesn't increase depth of template parameters, so need to be careful when gathering template parameters for instantiation. For the case: ``` template<typename T> struct X { struct impl; }; template <> struct X<int>::impl { template<int ct> int f() { return ct; }; }; ``` instantiation of `f` used to crash because type template parameter `int` of explicit specialization was taken into account, but non-type template parameter `ct` had zero depth and index so wrong parameter ended up inside of a wrong handler. Fixes https://github.com/llvm/llvm-project/issues/61159 Reviewed By: aaron.ballman, shafik Differential Revision: https://reviews.llvm.org/D155705 Added: clang/test/SemaTemplate/gh61159.cpp Modified: clang/docs/ReleaseNotes.rst clang/lib/Sema/SemaTemplateInstantiate.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 520e57532467db..d5f179ae828f73 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -677,6 +677,8 @@ Bug Fixes in This Version - Invalidate BlockDecl with invalid ParmVarDecl. Remove redundant dump of BlockDecl's ParmVarDecl (`#64005 <https://github.com/llvm/llvm-project/issues/64005>_`) +- Fix crash on nested templated class with template function call. + (`#61159 <https://github.com/llvm/llvm-project/issues/61159>_`) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index f7e81d509c1cbc..8702e2ca3a1b3b 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -258,6 +258,11 @@ Response HandleRecordDecl(const CXXRecordDecl *Rec, /*Final=*/false); } + if (const MemberSpecializationInfo *MSInfo = + Rec->getMemberSpecializationInfo()) + if (MSInfo->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) + return Response::Done(); + bool IsFriend = Rec->getFriendObjectKind() || (Rec->getDescribedClassTemplate() && Rec->getDescribedClassTemplate()->getFriendObjectKind()); diff --git a/clang/test/SemaTemplate/gh61159.cpp b/clang/test/SemaTemplate/gh61159.cpp new file mode 100644 index 00000000000000..d430d4c0b4cdd5 --- /dev/null +++ b/clang/test/SemaTemplate/gh61159.cpp @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s +// expected-no-diagnostics + +namespace GH61159 { +template <typename T> struct X { + struct I; +}; + +template <> struct X<int>::I { + template <int ct> constexpr int f() { return ct; }; + + int data = 3; +}; + +template <typename T> struct X<T>::I { + template <T ct> constexpr T f() { return ct + 1; }; + T data = 7; +}; + +static_assert(X<int>::I{}.f<17>() == 17); +static_assert(X<int>::I{}.data == 3); +static_assert(X<short>::I{}.data == 7); +static_assert(X<short>::I{}.f<18>() == 19); + +template <typename T> struct Y { + struct I; +}; + +template <> struct Y<int> { + struct I { + template <int ct> constexpr int f() { return ct; }; + int data = 3; + }; +}; + +static_assert(Y<int>::I{}.f<17>() == 17); +static_assert(Y<int>::I{}.data == 3); + +} // namespace GH61159 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits