[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