Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit abf96f4

Browse files
committed
Improve support for 'decltype(auto)' in template template parameter matching.
A 'decltype(auto)' parameter can match any other kind of non-type template parameter, so should be usable in place of any other parameter in a template template argument. The standard is sadly extremely unclear on how this is supposed to work, but this seems like the obviously-correct result. It's less clear whether an 'auto' parameter should be able to match 'decltype(auto)', since the former cannot be used if the latter turns out to be used for a reference type, but if we disallow that then consistency suggests we should also disallow 'auto' matching 'T' for the same reason, defeating intended use cases of the feature. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@295866 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent a745be5 commit abf96f4

File tree

2 files changed

+20
-6
lines changed

2 files changed

+20
-6
lines changed

lib/Sema/SemaTemplate.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -5666,6 +5666,19 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
56665666

56675667
// If the parameter type somehow involves auto, deduce the type now.
56685668
if (getLangOpts().CPlusPlus1z && ParamType->isUndeducedType()) {
5669+
// During template argument deduction, we allow 'decltype(auto)' to
5670+
// match an arbitrary dependent argument.
5671+
// FIXME: The language rules don't say what happens in this case.
5672+
// FIXME: We get an opaque dependent type out of decltype(auto) if the
5673+
// expression is merely instantiation-dependent; is this enough?
5674+
if (CTAK == CTAK_Deduced && Arg->isTypeDependent()) {
5675+
auto *AT = dyn_cast<AutoType>(ParamType);
5676+
if (AT && AT->isDecltypeAuto()) {
5677+
Converted = TemplateArgument(Arg);
5678+
return Arg;
5679+
}
5680+
}
5681+
56695682
// When checking a deduced template argument, deduce from its type even if
56705683
// the type is dependent, in order to check the types of non-type template
56715684
// arguments line up properly in partial ordering.

test/SemaTemplate/temp_arg_template_cxx1z.cpp

+7-6
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,13 @@ namespace Auto {
103103
TDecltypeAuto<Int> dai; // expected-error {{different template parameters}}
104104
TDecltypeAuto<IntPtr> daip; // expected-error {{different template parameters}}
105105

106-
// FIXME: It's completely unclear what should happen here. A case can be made
107-
// that 'auto' is more specialized, because it's always a prvalue, whereas
108-
// 'decltype(auto)' could have any value category. Under that interpretation,
109-
// we get the following results entirely backwards:
110-
TAuto<DecltypeAuto> ada; // expected-error {{different template parameters}}
111-
TAutoPtr<DecltypeAuto> apda; // expected-error {{different template parameters}}
106+
// FIXME: It's completely unclear what should happen here, but these results
107+
// seem at least plausible:
108+
TAuto<DecltypeAuto> ada;
109+
TAutoPtr<DecltypeAuto> apda;
110+
// Perhaps this case should be invalid, as there are valid 'decltype(auto)'
111+
// parameters (such as 'user-defined-type &') that are not valid 'auto'
112+
// parameters.
112113
TDecltypeAuto<Auto> daa;
113114
TDecltypeAuto<AutoPtr> daa; // expected-error {{different template parameters}}
114115

0 commit comments

Comments
 (0)