From 265c344ef816a8573562fa27022b8008e0f58198 Mon Sep 17 00:00:00 2001 From: Richard Trieu Date: Tue, 5 Apr 2016 21:13:54 +0000 Subject: [PATCH] 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. llvm-svn: 265467 --- .../include/clang/Basic/DiagnosticSemaKinds.td | 2 +- clang/lib/Sema/SemaTemplate.cpp | 18 ++++++++++++------ clang/test/SemaCXX/using-decl-templates.cpp | 2 +- clang/test/SemaTemplate/template-id-expr.cpp | 6 ++++++ 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 39212e31b19a..35adb6e8d434 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/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/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 18b739df7f5f..fdb7d762d294 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/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/clang/test/SemaCXX/using-decl-templates.cpp b/clang/test/SemaCXX/using-decl-templates.cpp index 8314688bcbc7..d766bb3ac6bf 100644 --- a/clang/test/SemaCXX/using-decl-templates.cpp +++ b/clang/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/clang/test/SemaTemplate/template-id-expr.cpp b/clang/test/SemaTemplate/template-id-expr.cpp index 4416f92723ad..499d289ee675 100644 --- a/clang/test/SemaTemplate/template-id-expr.cpp +++ b/clang/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