Author: rsmith Date: Thu Dec 22 20:00:24 2016 New Revision: 290403 URL: http://llvm.org/viewvc/llvm-project?rev=290403&view=rev Log: Only substitute into type of non-type template parameter once, rather than twice, in finalization of template argument deduction.
This is a re-commit of r290310 (reverted in r290329); the bug found by the buildbots was fixed in r290399 (we would sometimes build a deduced template argument with a bogus type). Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=290403&r1=290402&r2=290403&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Thu Dec 22 20:00:24 2016 @@ -2072,7 +2072,8 @@ static bool isSameTemplateArg(ASTContext /// /// \param NTTPType For a declaration template argument, the type of /// the non-type template parameter that corresponds to this template -/// argument. +/// argument. Can be null if no type sugar is available to add to the +/// type from the template argument. /// /// \param Loc The source location to use for the resulting template /// argument. @@ -2088,12 +2089,16 @@ Sema::getTrivialTemplateArgumentLoc(cons Arg, Context.getTrivialTypeSourceInfo(Arg.getAsType(), Loc)); case TemplateArgument::Declaration: { + if (NTTPType.isNull()) + NTTPType = Arg.getParamTypeForDecl(); Expr *E = BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc) .getAs<Expr>(); return TemplateArgumentLoc(TemplateArgument(E), E); } case TemplateArgument::NullPtr: { + if (NTTPType.isNull()) + NTTPType = Arg.getNullPtrType(); Expr *E = BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc) .getAs<Expr>(); return TemplateArgumentLoc(TemplateArgument(NTTPType, /*isNullPtr*/true), @@ -2144,31 +2149,13 @@ ConvertDeducedTemplateArgument(Sema &S, TemplateDeductionInfo &Info, bool InFunctionTemplate, SmallVectorImpl<TemplateArgument> &Output) { - // First, for a non-type template parameter type that is - // initialized by a declaration, we need the type of the - // corresponding non-type template parameter. - QualType NTTPType; - if (NonTypeTemplateParmDecl *NTTP = - dyn_cast<NonTypeTemplateParmDecl>(Param)) { - NTTPType = NTTP->getType(); - if (NTTPType->isDependentType()) { - TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Output); - NTTPType = S.SubstType(NTTPType, - MultiLevelTemplateArgumentList(TemplateArgs), - NTTP->getLocation(), - NTTP->getDeclName()); - if (NTTPType.isNull()) - return true; - } - } - auto ConvertArg = [&](DeducedTemplateArgument Arg, unsigned ArgumentPackIndex) { // Convert the deduced template argument into a template // argument that we can check, almost as if the user had written // the template argument explicitly. TemplateArgumentLoc ArgLoc = - S.getTrivialTemplateArgumentLoc(Arg, NTTPType, Info.getLocation()); + S.getTrivialTemplateArgumentLoc(Arg, QualType(), Info.getLocation()); // Check the template argument, converting it as necessary. return S.CheckTemplateArgument( @@ -2200,22 +2187,28 @@ ConvertDeducedTemplateArgument(Sema &S, } // If the pack is empty, we still need to substitute into the parameter - // itself, in case that substitution fails. For non-type parameters, we did - // this above. For type parameters, no substitution is ever required. - auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param); - if (TTP && PackedArgsBuilder.empty()) { - // Set up a template instantiation context. + // itself, in case that substitution fails. + if (PackedArgsBuilder.empty()) { LocalInstantiationScope Scope(S); - Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template, - TTP, Output, - Template->getSourceRange()); - if (Inst.isInvalid()) - return true; - TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Output); - if (!S.SubstDecl(TTP, S.CurContext, - MultiLevelTemplateArgumentList(TemplateArgs))) - return true; + MultiLevelTemplateArgumentList Args(TemplateArgs); + + if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) { + Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template, + NTTP, Output, + Template->getSourceRange()); + if (Inst.isInvalid() || + S.SubstType(NTTP->getType(), Args, NTTP->getLocation(), + NTTP->getDeclName()).isNull()) + return true; + } else if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Param)) { + Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template, + TTP, Output, + Template->getSourceRange()); + if (Inst.isInvalid() || !S.SubstDecl(TTP, S.CurContext, Args)) + return true; + } + // For type parameters, no substitution is ever required. } // Create the resulting argument pack. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits