[PATCH] D25942: Fix crash in implicit default constructor creation for a template record specialization that has a field declaration with an initializer expression

Alex Lorenz via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 27 07:39:42 PDT 2016


arphaman updated this revision to Diff 76029.
arphaman marked an inline comment as done.
arphaman added a comment.

The updated patch follows Richard's explanation and fixes the problem by checking if `CTD` is a member specialization without irrelevant definition checks.


Repository:
  rL LLVM

https://reviews.llvm.org/D25942

Files:
  lib/AST/DeclCXX.cpp
  test/CodeGenCXX/cxx11-crashes.cpp
  test/Modules/cxx-templates.cpp


Index: test/Modules/cxx-templates.cpp
===================================================================
--- test/Modules/cxx-templates.cpp
+++ test/Modules/cxx-templates.cpp
@@ -199,7 +199,7 @@
     cls<char*> uk4; // expected-error 1+{{partial specialization of 'cls<type-parameter-0-0 *>' 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}}
-    cls<void>::nested_cls_t<char> unk3; // expected-error 1+{{explicit specialization 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}} expected-error 1+{{definition of}}
 
     // For enums, uses that would trigger instantiations of definitions are not
     // allowed.
Index: test/CodeGenCXX/cxx11-crashes.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/cxx11-crashes.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 %s -o - | FileCheck %s
+
+namespace rd28886662 {
+
+template<typename T>
+class A {
+public:
+  template<int i>
+  struct Inner;
+};
+
+template<>
+template<int i>
+struct A<int>::Inner {
+  int member = 42; // should be ok
+};
+
+int foo() {
+  return A<int>::Inner<0>().member;
+}
+
+// CHECK: _ZN10rd288866621AIiE5InnerILi0EEC2Ev
+// CHECK: store i32 42, i32* %member
+
+template<typename T>
+class B {
+public:
+  template<int i>
+  struct Inner;
+};
+
+template<typename T>
+template<int i>
+struct B<T>::Inner {
+  int member = 21;
+};
+
+int bar() {
+  return B<int>::Inner<0>().member;
+}
+
+// CHECK: _ZN10rd288866621BIiE5InnerILi0EEC2Ev
+// CHECK: store i32 21, i32* %member
+
+}
Index: lib/AST/DeclCXX.cpp
===================================================================
--- lib/AST/DeclCXX.cpp
+++ lib/AST/DeclCXX.cpp
@@ -1346,10 +1346,14 @@
   if (auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(this)) {
     auto From = TD->getInstantiatedFrom();
     if (auto *CTD = From.dyn_cast<ClassTemplateDecl *>()) {
-      while (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate()) {
-        if (NewCTD->isMemberSpecialization())
-          break;
-        CTD = NewCTD;
+      while (true) {
+        if (!CTD->isMemberSpecialization()) {
+          if (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate()) {
+            CTD = NewCTD;
+            continue;
+          }
+        }
+        break;
       }
       return CTD->getTemplatedDecl()->getDefinition();
     }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D25942.76029.patch
Type: text/x-patch
Size: 2782 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20161027/820aa061/attachment.bin>


More information about the cfe-commits mailing list