Fix crash if substitution fails during deduction of variable template partial specialization arguments.

llvm-svn: 290484
This commit is contained in:
Richard Smith 2016-12-24 04:20:31 +00:00
parent 792c22dbd4
commit e68a38f0a8
4 changed files with 32 additions and 24 deletions

View File

@ -4145,9 +4145,9 @@ def note_explicit_template_arg_substitution_here : Note<
def note_function_template_deduction_instantiation_here : Note<
"while substituting deduced template arguments into function template %0 "
"%1">;
def note_partial_spec_deduct_instantiation_here : Note<
"during template argument deduction for class template partial "
"specialization %0 %1">;
def note_deduced_template_arg_substitution_here : Note<
"during template argument deduction for %select{class|variable}0 template "
"partial specialization %1 %2">;
def note_prior_template_arg_substitution : Note<
"while substituting prior template arguments into %select{non-type|template}0"
" template parameter%1 %2">;

View File

@ -6749,7 +6749,7 @@ public:
/// We are substituting template argument determined as part of
/// template argument deduction for either a class template
/// partial specialization or a function template. The
/// Entity is either a ClassTemplatePartialSpecializationDecl or
/// Entity is either a {Class|Var}TemplatePartialSpecializationDecl or
/// a FunctionTemplateDecl.
DeducedTemplateArgumentSubstitution,

View File

@ -484,20 +484,9 @@ void Sema::PrintInstantiationStack() {
break;
}
case ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution:
if (ClassTemplatePartialSpecializationDecl *PartialSpec =
dyn_cast<ClassTemplatePartialSpecializationDecl>(Active->Entity)) {
Diags.Report(Active->PointOfInstantiation,
diag::note_partial_spec_deduct_instantiation_here)
<< PartialSpec
<< getTemplateArgumentBindingsText(
PartialSpec->getTemplateParameters(),
Active->TemplateArgs,
Active->NumTemplateArgs)
<< Active->InstantiationRange;
} else {
FunctionTemplateDecl *FnTmpl
= cast<FunctionTemplateDecl>(Active->Entity);
case ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution: {
if (FunctionTemplateDecl *FnTmpl =
dyn_cast<FunctionTemplateDecl>(Active->Entity)) {
Diags.Report(Active->PointOfInstantiation,
diag::note_function_template_deduction_instantiation_here)
<< FnTmpl
@ -505,8 +494,30 @@ void Sema::PrintInstantiationStack() {
Active->TemplateArgs,
Active->NumTemplateArgs)
<< Active->InstantiationRange;
} else {
bool IsVar = isa<VarTemplateDecl>(Active->Entity) ||
isa<VarTemplateSpecializationDecl>(Active->Entity);
TemplateParameterList *Params;
if (auto *D = dyn_cast<ClassTemplatePartialSpecializationDecl>(
Active->Entity)) {
Params = D->getTemplateParameters();
} else if (auto *D = dyn_cast<VarTemplatePartialSpecializationDecl>(
Active->Entity)) {
Params = D->getTemplateParameters();
} else {
llvm_unreachable("unexpected template kind");
}
//<< Context.getTypeDeclType(PartialSpec)
Diags.Report(Active->PointOfInstantiation,
diag::note_deduced_template_arg_substitution_here)
<< IsVar << cast<NamedDecl>(Active->Entity)
<< getTemplateArgumentBindingsText(Params, Active->TemplateArgs,
Active->NumTemplateArgs)
<< Active->InstantiationRange;
}
break;
}
case ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation: {
ParmVarDecl *Param = cast<ParmVarDecl>(Active->Entity);

View File

@ -338,16 +338,13 @@ namespace member_pointer {
}
namespace deduction_substitution_failure {
template<typename T> struct Fail { typedef typename T::error error; }; // expected-error {{prior to '::'}}
template<typename T> struct Fail { typedef typename T::error error; }; // expected-error 2{{prior to '::'}}
template<typename T, typename U> struct A {};
template<typename T> struct A<T, typename Fail<T>::error> {}; // expected-note {{instantiation of}}
A<int, int> ai; // expected-note {{during template argument deduction for class template partial specialization 'A<T, typename Fail<T>::error>' [with T = int]}}
// FIXME: This tickles an assertion.
#if 0
template<typename T, typename U> int B; // expected-warning 0-1 {{extension}}
template<typename T> int B<T, typename Fail<T>::error> {};
int bi = B<char, char>;
#endif
template<typename T> int B<T, typename Fail<T>::error> {}; // expected-note {{instantiation of}}
int bi = B<char, char>; // expected-note {{during template argument deduction for variable template partial specialization 'B<T, typename Fail<T>::error>' [with T = char]}}
}