forked from OSchip/llvm-project
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
This commit is contained in:
parent
1de3c7e790
commit
265c344ef8
|
@ -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">;
|
||||
|
|
|
@ -7277,15 +7277,21 @@ Sema::ActOnExplicitInstantiation(Scope *S,
|
|||
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);
|
||||
ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(TD);
|
||||
|
||||
if (!ClassTemplate) {
|
||||
unsigned ErrorKind = 0;
|
||||
if (isa<TypeAliasTemplateDecl>(TD)) {
|
||||
ErrorKind = 4;
|
||||
} else if (isa<TemplateTemplateParmDecl>(TD)) {
|
||||
ErrorKind = 5;
|
||||
}
|
||||
|
||||
Diag(TemplateNameLoc, diag::err_tag_reference_non_tag) << ErrorKind;
|
||||
Diag(TD->getLocation(), diag::note_previous_use);
|
||||
return true;
|
||||
}
|
||||
|
||||
ClassTemplateDecl *ClassTemplate = cast<ClassTemplateDecl>(TD);
|
||||
|
||||
if (!isAcceptableTagRedeclaration(ClassTemplate->getTemplatedDecl(),
|
||||
Kind, /*isDefinition*/false, KWLoc,
|
||||
ClassTemplate->getIdentifier())) {
|
||||
|
|
|
@ -90,5 +90,5 @@ 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}}
|
||||
template struct APtr<int>; // expected-error{{elaborated type refers to a type alias template}}
|
||||
}
|
||||
|
|
|
@ -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 <template <typename> class D> // expected-note{{previous use is here}}
|
||||
class E {
|
||||
template class D<C>; // expected-error {{elaborated type refers to a template template argument}}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue