Index: lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- lib/Sema/SemaTemplateDeduction.cpp +++ lib/Sema/SemaTemplateDeduction.cpp @@ -3190,6 +3190,40 @@ hasDeducibleTemplateParameters(Sema &S, FunctionTemplateDecl *FunctionTemplate, QualType T); +static Sema::TemplateDeductionResult DeduceTemplateArgumentByListElement( + Sema &S, TemplateParameterList *TemplateParams, QualType ParamType, + Expr *Arg, TemplateDeductionInfo &Info, + SmallVectorImpl &Deduced, unsigned TDF); + +/// \brief Attempt template argument deduction from an initializer list +/// deemed to be an argument in a function call. +static bool +DeduceFromInitializerList(Sema &S, TemplateParameterList *TemplateParams, + QualType AdjustedParamType, InitListExpr *ILE, + TemplateDeductionInfo &Info, + SmallVectorImpl &Deduced, + unsigned TDF, Sema::TemplateDeductionResult &Result) { + // If the argument is an initializer list then the parameter is an undeduced + // context, unless the parameter type is (reference to cv) + // std::initializer_list, in which case deduction is done for each element + // of the initializer list as-if it were an argument in a function call, and + // the result is the deduced type if it's the same for all elements. + QualType X; + if (!S.isStdInitializerList(AdjustedParamType, &X)) + return false; + + Result = Sema::TDK_Success; + + // Recurse down into the init list. + for (unsigned i = 0, e = ILE->getNumInits(); i < e; ++i) { + if ((Result = DeduceTemplateArgumentByListElement( + S, TemplateParams, X, ILE->getInit(i), Info, Deduced, TDF))) + return true; + } + + return true; +} + /// \brief Perform template argument deduction by matching a parameter type /// against a single expression, where the expression is an element of /// an initializer list that was originally matched against a parameter @@ -3204,19 +3238,13 @@ // Handle the case where an init list contains another init list as the // element. if (InitListExpr *ILE = dyn_cast(Arg)) { - QualType X; - if (!S.isStdInitializerList(ParamType.getNonReferenceType(), &X)) + Sema::TemplateDeductionResult Result; + if (!DeduceFromInitializerList(S, TemplateParams, + ParamType.getNonReferenceType(), ILE, Info, + Deduced, TDF, Result)) return Sema::TDK_Success; // Just ignore this expression. - // Recurse down into the init list. - for (unsigned i = 0, e = ILE->getNumInits(); i < e; ++i) { - if (Sema::TemplateDeductionResult Result = - DeduceTemplateArgumentByListElement(S, TemplateParams, X, - ILE->getInit(i), - Info, Deduced, TDF)) - return Result; - } - return Sema::TDK_Success; + return Result; } // For all other cases, just match by type. @@ -3335,22 +3363,14 @@ // If the argument is an initializer list ... if (InitListExpr *ILE = dyn_cast(Arg)) { - // ... then the parameter is an undeduced context, unless the parameter - // type is (reference to cv) std::initializer_list, in which case - // deduction is done for each element of the initializer list, and the - // result is the deduced type if it's the same for all elements. - QualType X; + TemplateDeductionResult Result; // Removing references was already done. - if (!isStdInitializerList(ParamType, &X)) + if (!DeduceFromInitializerList(*this, TemplateParams, ParamType, ILE, + Info, Deduced, TDF, Result)) continue; - for (unsigned i = 0, e = ILE->getNumInits(); i < e; ++i) { - if (TemplateDeductionResult Result = - DeduceTemplateArgumentByListElement(*this, TemplateParams, X, - ILE->getInit(i), - Info, Deduced, TDF)) - return Result; - } + if (Result) + return Result; // Don't track the argument type, since an initializer list has none. continue; } @@ -3406,19 +3426,15 @@ // As above, initializer lists need special handling. if (InitListExpr *ILE = dyn_cast(Arg)) { - QualType X; - if (!isStdInitializerList(ParamType, &X)) { + TemplateDeductionResult Result; + if (!DeduceFromInitializerList(*this, TemplateParams, ParamType, ILE, + Info, Deduced, TDF, Result)) { ++ArgIdx; break; } - for (unsigned i = 0, e = ILE->getNumInits(); i < e; ++i) { - if (TemplateDeductionResult Result = - DeduceTemplateArgumentsByTypeMatch(*this, TemplateParams, X, - ILE->getInit(i)->getType(), - Info, Deduced, TDF)) - return Result; - } + if (Result) + return Result; } else { // Keep track of the argument type and corresponding argument index, Index: test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp =================================================================== --- test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp +++ test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -275,3 +275,10 @@ {0} ); } + +namespace ParameterPackNestedInitializerLists_PR23904c3 { + template + void f(std::initializer_list> ...tt); + + void foo() { f({{0}}, {{'\0'}}); } +}