summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-12-24 04:20:31 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-12-24 04:20:31 +0000
commite68a38f0a8abcd86da39917f035d69f1c8c12a62 (patch)
tree3fc7d24667e533ad843bfd7499755619ae7d00bd
parent792c22dbd477c26955e86577d7e49f981060c644 (diff)
downloadbcm5719-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.td6
-rw-r--r--clang/include/clang/Sema/Sema.h2
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp37
-rw-r--r--clang/test/SemaTemplate/deduction.cpp9
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]}}
}
OpenPOWER on IntegriCloud