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}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits