If class is absent from instantiation and is incomplete, instantiate it as
incomplete class thus avoiding compiler crash.
This change fixes PR18653.

http://reviews.llvm.org/D8281

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

Index: lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiate.cpp
+++ lib/Sema/SemaTemplateInstantiate.cpp
@@ -2792,6 +2792,12 @@
       isa<TemplateTemplateParmDecl>(D))
     return nullptr;
 
+  // If the declaration we are looking for is an incomplete type declaration, 
we
+  // may not have a chance to instantiate it.
+  if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
+    if (TD->getTypeForDecl()->isIncompleteType())
+      return nullptr;
+
   // If we didn't find the decl, then we either have a sema bug, or we have a
   // forward reference to a label declaration.  Return null to indicate that
   // we have an uninstantiated label.
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4399,6 +4399,15 @@
         isa<TemplateTemplateParmDecl>(D))
       return D;
 
+    // If the declaration we are looking for is an incomplete type declaration,
+    // we may not have a chance to instantiate it.
+    if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
+      if (TD->getTypeForDecl()->isIncompleteType()) {
+        Decl *Inst = SubstDecl(D, CurContext, TemplateArgs);
+        CurrentInstantiationScope->InstantiatedLocal(D, Inst);
+        return cast<TypeDecl>(Inst);
+      }
+
     if (D->isInvalidDecl())
       return nullptr;
 
Index: test/SemaTemplate/instantiate-local-class.cpp
===================================================================
--- test/SemaTemplate/instantiate-local-class.cpp
+++ test/SemaTemplate/instantiate-local-class.cpp
@@ -194,3 +194,13 @@
   void f() { F<int>(); }
 };
 }
+
+namespace PR18653 {
+  template <class T> void f();
+  template <class T> struct str {
+    void m() {
+      f<class newclass>();
+    }
+  };
+  template struct str<int>;
+}

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiate.cpp
+++ lib/Sema/SemaTemplateInstantiate.cpp
@@ -2792,6 +2792,12 @@
       isa<TemplateTemplateParmDecl>(D))
     return nullptr;
 
+  // If the declaration we are looking for is an incomplete type declaration, we
+  // may not have a chance to instantiate it.
+  if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
+    if (TD->getTypeForDecl()->isIncompleteType())
+      return nullptr;
+
   // If we didn't find the decl, then we either have a sema bug, or we have a
   // forward reference to a label declaration.  Return null to indicate that
   // we have an uninstantiated label.
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4399,6 +4399,15 @@
         isa<TemplateTemplateParmDecl>(D))
       return D;
 
+    // If the declaration we are looking for is an incomplete type declaration,
+    // we may not have a chance to instantiate it.
+    if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
+      if (TD->getTypeForDecl()->isIncompleteType()) {
+        Decl *Inst = SubstDecl(D, CurContext, TemplateArgs);
+        CurrentInstantiationScope->InstantiatedLocal(D, Inst);
+        return cast<TypeDecl>(Inst);
+      }
+
     if (D->isInvalidDecl())
       return nullptr;
 
Index: test/SemaTemplate/instantiate-local-class.cpp
===================================================================
--- test/SemaTemplate/instantiate-local-class.cpp
+++ test/SemaTemplate/instantiate-local-class.cpp
@@ -194,3 +194,13 @@
   void f() { F<int>(); }
 };
 }
+
+namespace PR18653 {
+  template <class T> void f();
+  template <class T> struct str {
+    void m() {
+      f<class newclass>();
+    }
+  };
+  template struct str<int>;
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to