From: Richard Trieu Date: Tue, 5 Apr 2016 21:13:54 +0000 (+0000) Subject: Fix a crash on invalid with template handling X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=499ed1eba714d86e29985c587a3bbd6b037c5d78;p=clang Fix a crash on invalid with template handling This is a fix for https://llvm.org/bugs/show_bug.cgi?id=25561 which was a crash on invalid. Change the handling of invalid decls to have a catch-all case to prevent unexpecting decls from triggering an assertion. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@265467 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 39212e31b1..35adb6e8d4 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -4322,7 +4322,7 @@ def err_redefinition_different_typedef : Error< "%select{typedef|type alias|type alias template}0 " "redefinition with different types%diff{ ($ vs $)|}1,2">; def err_tag_reference_non_tag : Error< - "elaborated type refers to %select{a non-tag type|a typedef|a type alias|a template|a type alias template}0">; + "elaborated type refers to %select{a non-tag type|a typedef|a type alias|a template|a type alias template|a template template argument}0">; def err_tag_reference_conflict : Error< "implicit declaration introduced by elaborated type conflicts with " "%select{a declaration|a typedef|a type alias|a template}0 of the same name">; diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 18b739df7f..fdb7d762d2 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -7277,15 +7277,21 @@ Sema::ActOnExplicitInstantiation(Scope *S, assert(Kind != TTK_Enum && "Invalid enum tag in class template explicit instantiation!"); - if (isa(TD)) { - Diag(KWLoc, diag::err_tag_reference_non_tag) << Kind; - Diag(TD->getTemplatedDecl()->getLocation(), - diag::note_previous_use); + ClassTemplateDecl *ClassTemplate = dyn_cast(TD); + + if (!ClassTemplate) { + unsigned ErrorKind = 0; + if (isa(TD)) { + ErrorKind = 4; + } else if (isa(TD)) { + ErrorKind = 5; + } + + Diag(TemplateNameLoc, diag::err_tag_reference_non_tag) << ErrorKind; + Diag(TD->getLocation(), diag::note_previous_use); return true; } - ClassTemplateDecl *ClassTemplate = cast(TD); - if (!isAcceptableTagRedeclaration(ClassTemplate->getTemplatedDecl(), Kind, /*isDefinition*/false, KWLoc, ClassTemplate->getIdentifier())) { diff --git a/test/SemaCXX/using-decl-templates.cpp b/test/SemaCXX/using-decl-templates.cpp index 8314688bcb..d766bb3ac6 100644 --- a/test/SemaCXX/using-decl-templates.cpp +++ b/test/SemaCXX/using-decl-templates.cpp @@ -90,5 +90,5 @@ namespace aliastemplateinst { template struct A { }; template using APtr = A; // expected-note{{previous use is here}} - template struct APtr; // expected-error{{elaborated type refers to a non-tag type}} + template struct APtr; // expected-error{{elaborated type refers to a type alias template}} } diff --git a/test/SemaTemplate/template-id-expr.cpp b/test/SemaTemplate/template-id-expr.cpp index 4416f92723..499d289ee6 100644 --- a/test/SemaTemplate/template-id-expr.cpp +++ b/test/SemaTemplate/template-id-expr.cpp @@ -96,3 +96,9 @@ void f5() { } template void f5<0>(); // expected-note {{in instantiation of function template specialization 'f5<0>' requested here}} + +class C {}; +template