diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-12-24 04:20:31 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-12-24 04:20:31 +0000 |
| commit | e68a38f0a8abcd86da39917f035d69f1c8c12a62 (patch) | |
| tree | 3fc7d24667e533ad843bfd7499755619ae7d00bd | |
| parent | 792c22dbd477c26955e86577d7e49f981060c644 (diff) | |
| download | bcm5719-llvm-e68a38f0a8abcd86da39917f035d69f1c8c12a62.tar.gz bcm5719-llvm-e68a38f0a8abcd86da39917f035d69f1c8c12a62.zip | |
Fix crash if substitution fails during deduction of variable template partial specialization arguments.
llvm-svn: 290484
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 6 | ||||
| -rw-r--r-- | clang/include/clang/Sema/Sema.h | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 37 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/deduction.cpp | 9 |
4 files changed, 31 insertions, 23 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index da8f532f3a8..5f59a10c1c1 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -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">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 47a5ca621a7..512a667f690 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -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, diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 382c23ce87f..4f2e74740df 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -484,29 +484,40 @@ void Sema::PrintInstantiationStack() { break; } - case ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution: - if (ClassTemplatePartialSpecializationDecl *PartialSpec = - dyn_cast<ClassTemplatePartialSpecializationDecl>(Active->Entity)) { + case ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution: { + if (FunctionTemplateDecl *FnTmpl = + dyn_cast<FunctionTemplateDecl>(Active->Entity)) { Diags.Report(Active->PointOfInstantiation, - diag::note_partial_spec_deduct_instantiation_here) - << PartialSpec - << getTemplateArgumentBindingsText( - PartialSpec->getTemplateParameters(), + diag::note_function_template_deduction_instantiation_here) + << FnTmpl + << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(), Active->TemplateArgs, Active->NumTemplateArgs) << Active->InstantiationRange; } else { - FunctionTemplateDecl *FnTmpl - = cast<FunctionTemplateDecl>(Active->Entity); + 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_function_template_deduction_instantiation_here) - << FnTmpl - << getTemplateArgumentBindingsText(FnTmpl->getTemplateParameters(), - Active->TemplateArgs, + 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); diff --git a/clang/test/SemaTemplate/deduction.cpp b/clang/test/SemaTemplate/deduction.cpp index 8cd4331755a..9471bac91c3 100644 --- a/clang/test/SemaTemplate/deduction.cpp +++ b/clang/test/SemaTemplate/deduction.cpp @@ -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]}} } |

