[clang] dcb8911 - [clang] Fix specialization of non-templated member classes of class templates
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 24 09:37:12 PDT 2023
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
More information about the cfe-commits
mailing list