From: Douglas Gregor Date: Fri, 3 Jun 2011 02:59:40 +0000 (+0000) Subject: When checking the instantiation of a default template argument against X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8735b294a257a07ca158c28094d7324f0adf889a;p=clang When checking the instantiation of a default template argument against the template parameter, perform the checking as a "specified" template argument rather than a "deduced" template argument; the latter implies stricter type checking that is not permitted for default template arguments. Also, cleanup our handling of substitution of explicit template arguments for a function template. We were actually performing some substitution of default arguments at this point! Fixes PR10069. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@132529 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 1aa7364d18..3761740d8c 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -2819,9 +2819,6 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, unsigned ArgIdx = 0; LocalInstantiationScope InstScope(*this, true); while (Param != ParamEnd) { - if (ArgIdx > NumArgs && PartialTemplateArgs) - break; - if (ArgIdx < NumArgs) { // If we have an expanded parameter pack, make sure we don't have too // many arguments. @@ -2862,6 +2859,16 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, continue; } + // If we're checking a partial template argument list, we're done. + if (PartialTemplateArgs) { + if ((*Param)->isTemplateParameterPack() && !ArgumentPack.empty()) + Converted.push_back(TemplateArgument::CreatePackCopy(Context, + ArgumentPack.data(), + ArgumentPack.size())); + + return Invalid; + } + // If we have a template parameter pack with no more corresponding // arguments, just break out now and we'll fill in the argument pack below. if ((*Param)->isTemplateParameterPack()) @@ -2887,7 +2894,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, // the default argument. if (TemplateTypeParmDecl *TTP = dyn_cast(*Param)) { if (!TTP->hasDefaultArgument()) { - assert((Invalid || PartialTemplateArgs) && "Missing default argument"); + assert(Invalid && "Missing default argument"); break; } @@ -2905,7 +2912,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, } else if (NonTypeTemplateParmDecl *NTTP = dyn_cast(*Param)) { if (!NTTP->hasDefaultArgument()) { - assert((Invalid || PartialTemplateArgs) && "Missing default argument"); + assert(Invalid && "Missing default argument"); break; } @@ -2924,7 +2931,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, = cast(*Param); if (!TempParm->hasDefaultArgument()) { - assert((Invalid || PartialTemplateArgs) && "Missing default argument"); + assert(Invalid && "Missing default argument"); break; } @@ -2970,9 +2977,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, // in arguments for non-template parameter packs. if ((*Param)->isTemplateParameterPack()) { - if (PartialTemplateArgs && ArgumentPack.empty()) { - Converted.push_back(TemplateArgument()); - } else if (ArgumentPack.empty()) + if (ArgumentPack.empty()) Converted.push_back(TemplateArgument(0, 0)); else { Converted.push_back(TemplateArgument::CreatePackCopy(Context, diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index c4627eb1e3..ed1b671bf4 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -2314,7 +2314,7 @@ Sema::FinishTemplateArgumentDeduction(FunctionTemplateDecl *FunctionTemplate, FunctionTemplate->getLocation(), FunctionTemplate->getSourceRange().getEnd(), 0, Builder, - CTAK_Deduced)) { + CTAK_Specified)) { Info.Param = makeTemplateParameter( const_cast(TemplateParams->getParam(I))); // FIXME: These template arguments are temporary. Free them! diff --git a/test/CXX/temp/temp.param/p9-0x.cpp b/test/CXX/temp/temp.param/p9-0x.cpp index 17eca7f7e8..1dc6640fe2 100644 --- a/test/CXX/temp/temp.param/p9-0x.cpp +++ b/test/CXX/temp/temp.param/p9-0x.cpp @@ -50,3 +50,12 @@ namespace PR8748 { template struct Inner::X3 { }; template void Inner::f2() {} } + +namespace PR10069 { + template + T f(T x); + + void g() { + f(0); + } +}