diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -670,6 +670,8 @@ - Correcly diagnose jumps into statement expressions. This ensures the behavior of Clang is consistent with GCC. (`#63682 `_) +- Fix crash on nested templated class with template function call. + (`#61159 _`) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -258,6 +258,11 @@ /*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 --- /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 struct X { + struct I; +}; + +template <> struct X::I { + template constexpr int f() { return ct; }; + + int data = 3; +}; + +template struct X::I { + template constexpr T f() { return ct + 1; }; + T data = 7; +}; + +static_assert(X::I{}.f<17>() == 17); +static_assert(X::I{}.data == 3); +static_assert(X::I{}.data == 7); +static_assert(X::I{}.f<18>() == 19); + +template struct Y { + struct I; +}; + +template <> struct Y { + struct I { + template constexpr int f() { return ct; }; + int data = 3; + }; +}; + +static_assert(Y::I{}.f<17>() == 17); +static_assert(Y::I{}.data == 3); + +} // namespace GH61159