]> granicus.if.org Git - clang/commitdiff
Fix assert if an attempt is made to explicitly instantiate an alias template.
authorRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 22 Jun 2013 22:03:31 +0000 (22:03 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 22 Jun 2013 22:03:31 +0000 (22:03 +0000)
Patch by Ismail Pazarbasi!

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

lib/Sema/SemaTemplate.cpp
test/SemaCXX/using-decl-templates.cpp

index 7ad3131627017903cfa302dfaaaed3434401e02a..88b24a1702c39fa8342ca7af58a3a29cdb2c8384 100644 (file)
@@ -6341,14 +6341,22 @@ Sema::ActOnExplicitInstantiation(Scope *S,
                                  AttributeList *Attr) {
   // Find the class template we're specializing
   TemplateName Name = TemplateD.getAsVal<TemplateName>();
-  ClassTemplateDecl *ClassTemplate
-    = cast<ClassTemplateDecl>(Name.getAsTemplateDecl());
-
+  TemplateDecl *TD = Name.getAsTemplateDecl();
   // Check that the specialization uses the same tag kind as the
   // original template.
   TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
   assert(Kind != TTK_Enum &&
          "Invalid enum tag in class template explicit instantiation!");
+
+  if (isa<TypeAliasTemplateDecl>(TD)) {
+      Diag(KWLoc, diag::err_tag_reference_non_tag) << Kind;
+      Diag(TD->getTemplatedDecl()->getLocation(),
+           diag::note_previous_use);
+    return true;
+  }
+
+  ClassTemplateDecl *ClassTemplate = cast<ClassTemplateDecl>(TD);
+
   if (!isAcceptableTagRedeclaration(ClassTemplate->getTemplatedDecl(),
                                     Kind, /*isDefinition*/false, KWLoc,
                                     *ClassTemplate->getIdentifier())) {
index 2fc679564255fb0e51d2cdafcb5e36c22f9cc810..8314688bcbc7e688a5e040c880e64193e8dd9731 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
 
 template<typename T> struct A {
   void f() { }
@@ -85,3 +85,10 @@ template<typename T> class UsingTypenameNNS {
   using typename T::X;
   typename X::X x;
 };
+
+namespace aliastemplateinst {
+  template<typename T> struct A { };
+  template<typename T> using APtr = A<T*>; // expected-note{{previous use is here}}
+
+  template struct APtr<int>; // expected-error{{elaborated type refers to a non-tag type}}
+}