summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-12-25 08:05:23 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-12-25 08:05:23 +0000
commit87d263e870752d1bd724183bd88be47f6d2f6fed (patch)
tree7ec26efc2d949fc4aa854d8f6bc973708ed257c4 /clang/lib/Sema/SemaTemplate.cpp
parent31a46b48356a52ca33869e55b2af368e0b7a82aa (diff)
downloadbcm5719-llvm-87d263e870752d1bd724183bd88be47f6d2f6fed.tar.gz
bcm5719-llvm-87d263e870752d1bd724183bd88be47f6d2f6fed.zip
Fix some subtle wrong partial ordering bugs particularly with C++1z auto-typed
non-type template parameters. During partial ordering, when checking the substituted deduced template arguments match the original, check the types of non-type template arguments match even if they're dependent. The only way we get dependent types here is if they really represent types of the other template (which are supposed to be modeled as being substituted for unique, non-dependent types). In order to make this work for auto-typed non-type template arguments, we need to be able to perform auto deduction even when the initializer and (potentially) the auto type are dependent, support for which is the bulk of this patch. (Note that this requires the ability to deduce only a single level of a multi-level dependent type.) llvm-svn: 290511
Diffstat (limited to 'clang/lib/Sema/SemaTemplate.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp24
1 files changed, 15 insertions, 9 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index bbf1965eef4..766ed944b13 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -5008,9 +5008,15 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
// If the parameter type somehow involves auto, deduce the type now.
if (getLangOpts().CPlusPlus1z && ParamType->isUndeducedType()) {
+ // When checking a deduced template argument, deduce from its type even if
+ // the type is dependent, in order to check the types of non-type template
+ // arguments line up properly in partial ordering.
+ Optional<unsigned> Depth;
+ if (CTAK != CTAK_Specified)
+ Depth = Param->getDepth() + 1;
if (DeduceAutoType(
Context.getTrivialTypeSourceInfo(ParamType, Param->getLocation()),
- Arg, ParamType) == DAR_Failed) {
+ Arg, ParamType, Depth) == DAR_Failed) {
Diag(Arg->getExprLoc(),
diag::err_non_type_template_parm_type_deduction_failure)
<< Param->getDeclName() << Param->getType() << Arg->getType()
@@ -5029,14 +5035,6 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
}
}
- // If either the parameter has a dependent type or the argument is
- // type-dependent, there's nothing we can check now.
- if (ParamType->isDependentType() || Arg->isTypeDependent()) {
- // FIXME: Produce a cloned, canonical expression?
- Converted = TemplateArgument(Arg);
- return Arg;
- }
-
// We should have already dropped all cv-qualifiers by now.
assert(!ParamType.hasQualifiers() &&
"non-type template parameter type cannot be qualified");
@@ -5058,6 +5056,14 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
return ExprError();
}
+ // If either the parameter has a dependent type or the argument is
+ // type-dependent, there's nothing we can check now.
+ if (ParamType->isDependentType() || Arg->isTypeDependent()) {
+ // FIXME: Produce a cloned, canonical expression?
+ Converted = TemplateArgument(Arg);
+ return Arg;
+ }
+
if (getLangOpts().CPlusPlus1z) {
// C++1z [temp.arg.nontype]p1:
// A template-argument for a non-type template parameter shall be
OpenPOWER on IntegriCloud