r295866 - Improve support for 'decltype(auto)' in template template parameter matching.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 22 12:01:56 PST 2017
Author: rsmith
Date: Wed Feb 22 14:01:55 2017
New Revision: 295866
URL: http://llvm.org/viewvc/llvm-project?rev=295866&view=rev
Log:
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.
Modified:
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/SemaTemplate/temp_arg_template_cxx1z.cpp
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=295866&r1=295865&r2=295866&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Feb 22 14:01:55 2017
@@ -5666,6 +5666,19 @@ ExprResult Sema::CheckTemplateArgument(N
// If the parameter type somehow involves auto, deduce the type now.
if (getLangOpts().CPlusPlus1z && ParamType->isUndeducedType()) {
+ // During template argument deduction, we allow 'decltype(auto)' to
+ // match an arbitrary dependent argument.
+ // FIXME: The language rules don't say what happens in this case.
+ // FIXME: We get an opaque dependent type out of decltype(auto) if the
+ // expression is merely instantiation-dependent; is this enough?
+ if (CTAK == CTAK_Deduced && Arg->isTypeDependent()) {
+ auto *AT = dyn_cast<AutoType>(ParamType);
+ if (AT && AT->isDecltypeAuto()) {
+ Converted = TemplateArgument(Arg);
+ return Arg;
+ }
+ }
+
// 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.
Modified: cfe/trunk/test/SemaTemplate/temp_arg_template_cxx1z.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_arg_template_cxx1z.cpp?rev=295866&r1=295865&r2=295866&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/temp_arg_template_cxx1z.cpp (original)
+++ cfe/trunk/test/SemaTemplate/temp_arg_template_cxx1z.cpp Wed Feb 22 14:01:55 2017
@@ -103,12 +103,13 @@ namespace Auto {
TDecltypeAuto<Int> dai; // expected-error {{different template parameters}}
TDecltypeAuto<IntPtr> daip; // expected-error {{different template parameters}}
- // FIXME: It's completely unclear what should happen here. A case can be made
- // that 'auto' is more specialized, because it's always a prvalue, whereas
- // 'decltype(auto)' could have any value category. Under that interpretation,
- // we get the following results entirely backwards:
- TAuto<DecltypeAuto> ada; // expected-error {{different template parameters}}
- TAutoPtr<DecltypeAuto> apda; // expected-error {{different template parameters}}
+ // FIXME: It's completely unclear what should happen here, but these results
+ // seem at least plausible:
+ TAuto<DecltypeAuto> ada;
+ TAutoPtr<DecltypeAuto> apda;
+ // Perhaps this case should be invalid, as there are valid 'decltype(auto)'
+ // parameters (such as 'user-defined-type &') that are not valid 'auto'
+ // parameters.
TDecltypeAuto<Auto> daa;
TDecltypeAuto<AutoPtr> daa; // expected-error {{different template parameters}}
More information about the cfe-commits
mailing list