]> granicus.if.org Git - clang/commitdiff
Sema: Don't crash when trying to instantiate a local class with an invalid base specifier
authorDavid Majnemer <david.majnemer@gmail.com>
Sat, 22 Feb 2014 00:17:46 +0000 (00:17 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Sat, 22 Feb 2014 00:17:46 +0000 (00:17 +0000)
It was previously thought that Sema::InstantiateClass could not fail
from within this point in instantiate.

However, it can happen if the class is invalid some way (i.e. invalid
base specifier).

This fixes PR18907.

Differential Revision: http://llvm-reviews.chandlerc.com/D2850

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@201913 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplateInstantiateDecl.cpp
test/SemaTemplate/instantiate-local-class.cpp

index 7b84a06eaa80e2dff667298dbd7f84255650552b..6439b9208c4a10f9994af8c287c733b78caba241 100644 (file)
@@ -1187,14 +1187,11 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
   // DR1484 clarifies that the members of a local class are instantiated as part
   // of the instantiation of their enclosing entity.
   if (D->isCompleteDefinition() && D->isLocalClass()) {
-    if (SemaRef.InstantiateClass(D->getLocation(), Record, D, TemplateArgs,
-                                 TSK_ImplicitInstantiation,
-                                 /*Complain=*/true)) {
-      llvm_unreachable("InstantiateClass shouldn't fail here!");
-    } else {
-      SemaRef.InstantiateClassMembers(D->getLocation(), Record, TemplateArgs,
-                                      TSK_ImplicitInstantiation);
-    }
+    SemaRef.InstantiateClass(D->getLocation(), Record, D, TemplateArgs,
+                             TSK_ImplicitInstantiation,
+                             /*Complain=*/true);
+    SemaRef.InstantiateClassMembers(D->getLocation(), Record, TemplateArgs,
+                                    TSK_ImplicitInstantiation);
   }
   return Record;
 }
index 2bf24c2188e6c4c355b44d9482eb80ee4351b744..c9897b9c614b9e8584aa18ea13bf41ac5ebf0f50 100644 (file)
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -verify -std=c++11 %s
-// expected-no-diagnostics
 template<typename T>
 void f0() {
   struct X;
@@ -181,3 +180,17 @@ namespace PR14373 {
     return 0;
   }
 }
+
+namespace PR18907 {
+template <typename>
+class C : public C<int> {}; // expected-error{{within its own definition}}
+
+template <typename X>
+void F() {
+  struct A : C<X> {};
+}
+
+struct B {
+  void f() { F<int>(); }
+};
+}