Author: Mikhail Goncharov Date: 2024-10-11T14:47:38+02:00 New Revision: efcfa6e711689ada546c323316145ecd749d380a
URL: https://github.com/llvm/llvm-project/commit/efcfa6e711689ada546c323316145ecd749d380a DIFF: https://github.com/llvm/llvm-project/commit/efcfa6e711689ada546c323316145ecd749d380a.diff LOG: Revert "Reland: [clang] Finish implementation of P0522 (#111711)" See discussion in https://github.com/llvm/llvm-project/pull/111711 This reverts commit 6213aa5e58a7d32bdc82dd40322fb1bab83c4783. Added: Modified: clang/docs/ReleaseNotes.rst clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Sema/Sema.h clang/lib/Frontend/FrontendActions.cpp clang/lib/Sema/SemaTemplate.cpp clang/lib/Sema/SemaTemplateDeduction.cpp clang/lib/Sema/SemaTemplateInstantiate.cpp clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp clang/test/CXX/temp/temp.param/p12.cpp clang/test/Modules/cxx-templates.cpp clang/test/SemaCXX/make_integer_seq.cpp clang/test/SemaTemplate/cwg2398.cpp clang/test/SemaTemplate/temp_arg_nontype.cpp clang/test/SemaTemplate/temp_arg_template.cpp clang/test/SemaTemplate/temp_arg_template_p0522.cpp clang/test/Templight/templight-empty-entries-fix.cpp clang/test/Templight/templight-prior-template-arg.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 00376ce2a6008b..a7500196399622 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -177,10 +177,6 @@ C++23 Feature Support C++20 Feature Support ^^^^^^^^^^^^^^^^^^^^^ -C++17 Feature Support -^^^^^^^^^^^^^^^^^^^^^ -- The implementation of the relaxed template template argument matching rules is - more complete and reliable, and should provide more accurate diagnostics. Resolutions to C++ Defect Reports ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -338,10 +334,6 @@ Improvements to Clang's diagnostics - Clang now diagnoses when the result of a [[nodiscard]] function is discarded after being cast in C. Fixes #GH104391. -- Clang now properly explains the reason a template template argument failed to - match a template template parameter, in terms of the C++17 relaxed matching rules - instead of the old ones. - - Don't emit duplicated dangling diagnostics. (#GH93386). - Improved diagnostic when trying to befriend a concept. (#GH45182). @@ -451,8 +443,6 @@ Bug Fixes to C++ Support - Correctly check constraints of explicit instantiations of member functions. (#GH46029) - When performing partial ordering of function templates, clang now checks that the deduction was consistent. Fixes (#GH18291). -- Fixes to several issues in partial ordering of template template parameters, which - were documented in the test suite. - Fixed an assertion failure about a constraint of a friend function template references to a value with greater template depth than the friend function template. (#GH98258) - Clang now rebuilds the template parameters of out-of-line declarations and specializations in the context diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index f4a2d4a3f0656a..777ea1f37cea46 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -5262,13 +5262,6 @@ def note_template_arg_refers_here_func : Note< def err_template_arg_template_params_mismatch : Error< "template template argument has diff erent template parameters than its " "corresponding template template parameter">; -def note_template_arg_template_params_mismatch : Note< - "template template argument has diff erent template parameters than its " - "corresponding template template parameter">; -def err_non_deduced_mismatch : Error< - "could not match % diff {$ against $|types}0,1">; -def err_inconsistent_deduction : Error< - "conflicting deduction % diff {$ against $|types}0,1 for parameter">; def err_template_arg_not_integral_or_enumeral : Error< "non-type template argument of type %0 must have an integral or enumeration" " type">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 49c593bf88c989..24191fd688dc5a 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -12418,9 +12418,8 @@ class Sema final : public SemaBase { sema::TemplateDeductionInfo &Info); bool isTemplateTemplateParameterAtLeastAsSpecializedAs( - TemplateParameterList *PParam, TemplateDecl *PArg, TemplateDecl *AArg, - const DefaultArguments &DefaultArgs, SourceLocation ArgLoc, - bool IsDeduced); + TemplateParameterList *PParam, TemplateDecl *AArg, + const DefaultArguments &DefaultArgs, SourceLocation Loc, bool IsDeduced); /// Mark which template parameters are used in a given expression. /// @@ -12729,9 +12728,6 @@ class Sema final : public SemaBase { /// We are instantiating a type alias template declaration. TypeAliasTemplateInstantiation, - - /// We are performing partial ordering for template template parameters. - PartialOrderingTTP, } Kind; /// Was the enclosing context a non-instantiation SFINAE context? @@ -12953,12 +12949,6 @@ class Sema final : public SemaBase { TemplateDecl *Entity, BuildingDeductionGuidesTag, SourceRange InstantiationRange = SourceRange()); - struct PartialOrderingTTP {}; - /// \brief Note that we are partial ordering template template parameters. - InstantiatingTemplate(Sema &SemaRef, SourceLocation ArgLoc, - PartialOrderingTTP, TemplateDecl *PArg, - SourceRange InstantiationRange = SourceRange()); - /// Note that we have finished instantiating this template. void Clear(); diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index e4b462b9b0fd81..64f90c493c1055 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -457,8 +457,6 @@ class DefaultTemplateInstCallback : public TemplateInstantiationCallback { return "BuildingDeductionGuides"; case CodeSynthesisContext::TypeAliasTemplateInstantiation: return "TypeAliasTemplateInstantiation"; - case CodeSynthesisContext::PartialOrderingTTP: - return "PartialOrderingTTP"; } return ""; } diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 226c1172a059d4..c7d48b81bc0347 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -5502,7 +5502,8 @@ bool Sema::CheckTemplateArgumentList( DefaultArgs && ParamIdx >= DefaultArgs.StartPos) { // All written arguments should have been consumed by this point. assert(ArgIdx == NumArgs && "bad default argument deduction"); - if (ParamIdx == DefaultArgs.StartPos) { + // FIXME: Don't ignore parameter packs. + if (ParamIdx == DefaultArgs.StartPos && !(*Param)->isParameterPack()) { assert(Param + DefaultArgs.Args.size() <= ParamEnd); // Default arguments from a DeducedTemplateName are already converted. for (const TemplateArgument &DefArg : DefaultArgs.Args) { @@ -5727,9 +5728,8 @@ bool Sema::CheckTemplateArgumentList( // pack expansions; they might be empty. This can happen even if // PartialTemplateArgs is false (the list of arguments is complete but // still dependent). - if (PartialOrderingTTP || - (CurrentInstantiationScope && - CurrentInstantiationScope->getPartiallySubstitutedPack())) { + if (ArgIdx < NumArgs && CurrentInstantiationScope && + CurrentInstantiationScope->getPartiallySubstitutedPack()) { while (ArgIdx < NumArgs && NewArgs[ArgIdx].getArgument().isPackExpansion()) { const TemplateArgument &Arg = NewArgs[ArgIdx++].getArgument(); @@ -7327,46 +7327,64 @@ bool Sema::CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param, << Template; } - if (!getLangOpts().RelaxedTemplateTemplateArgs) - return !TemplateParameterListsAreEqual( - Template->getTemplateParameters(), Params, /*Complain=*/true, - TPL_TemplateTemplateArgumentMatch, Arg.getLocation()); - // C++1z [temp.arg.template]p3: (DR 150) // A template-argument matches a template template-parameter P when P // is at least as specialized as the template-argument A. - if (!isTemplateTemplateParameterAtLeastAsSpecializedAs( - Params, Param, Template, DefaultArgs, Arg.getLocation(), IsDeduced)) - return true; - // P2113 - // C++20[temp.func.order]p2 - // [...] If both deductions succeed, the partial ordering selects the - // more constrained template (if one exists) as determined below. - SmallVector<const Expr *, 3> ParamsAC, TemplateAC; - Params->getAssociatedConstraints(ParamsAC); - // C++20[temp.arg.template]p3 - // [...] In this comparison, if P is unconstrained, the constraints on A - // are not considered. - if (ParamsAC.empty()) - return false; + if (getLangOpts().RelaxedTemplateTemplateArgs) { + // Quick check for the common case: + // If P contains a parameter pack, then A [...] matches P if each of A's + // template parameters matches the corresponding template parameter in + // the template-parameter-list of P. + if (TemplateParameterListsAreEqual( + Template->getTemplateParameters(), Params, false, + TPL_TemplateTemplateArgumentMatch, Arg.getLocation()) && + // If the argument has no associated constraints, then the parameter is + // definitely at least as specialized as the argument. + // Otherwise - we need a more thorough check. + !Template->hasAssociatedConstraints()) + return false; - Template->getAssociatedConstraints(TemplateAC); + if (isTemplateTemplateParameterAtLeastAsSpecializedAs( + Params, Template, DefaultArgs, Arg.getLocation(), IsDeduced)) { + // P2113 + // C++20[temp.func.order]p2 + // [...] If both deductions succeed, the partial ordering selects the + // more constrained template (if one exists) as determined below. + SmallVector<const Expr *, 3> ParamsAC, TemplateAC; + Params->getAssociatedConstraints(ParamsAC); + // C++2a[temp.arg.template]p3 + // [...] In this comparison, if P is unconstrained, the constraints on A + // are not considered. + if (ParamsAC.empty()) + return false; - bool IsParamAtLeastAsConstrained; - if (IsAtLeastAsConstrained(Param, ParamsAC, Template, TemplateAC, - IsParamAtLeastAsConstrained)) - return true; - if (!IsParamAtLeastAsConstrained) { - Diag(Arg.getLocation(), - diag::err_template_template_parameter_not_at_least_as_constrained) - << Template << Param << Arg.getSourceRange(); - Diag(Param->getLocation(), diag::note_entity_declared_at) << Param; - Diag(Template->getLocation(), diag::note_entity_declared_at) << Template; - MaybeEmitAmbiguousAtomicConstraintsDiagnostic(Param, ParamsAC, Template, - TemplateAC); - return true; + Template->getAssociatedConstraints(TemplateAC); + + bool IsParamAtLeastAsConstrained; + if (IsAtLeastAsConstrained(Param, ParamsAC, Template, TemplateAC, + IsParamAtLeastAsConstrained)) + return true; + if (!IsParamAtLeastAsConstrained) { + Diag(Arg.getLocation(), + diag::err_template_template_parameter_not_at_least_as_constrained) + << Template << Param << Arg.getSourceRange(); + Diag(Param->getLocation(), diag::note_entity_declared_at) << Param; + Diag(Template->getLocation(), diag::note_entity_declared_at) + << Template; + MaybeEmitAmbiguousAtomicConstraintsDiagnostic(Param, ParamsAC, Template, + TemplateAC); + return true; + } + return false; + } + // FIXME: Produce better diagnostics for deduction failures. } - return false; + + return !TemplateParameterListsAreEqual(Template->getTemplateParameters(), + Params, + true, + TPL_TemplateTemplateArgumentMatch, + Arg.getLocation()); } static Sema::SemaDiagnosticBuilder noteLocation(Sema &S, const NamedDecl &Decl, diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 03ff8145e3b4ac..d106874c4c5bda 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -145,9 +145,7 @@ static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( PartialOrderingKind POK, bool DeducedFromArrayBound, bool *HasDeducedAnyParam); -/// What directions packs are allowed to match non-packs. -enum class PackFold { ParameterToArgument, ArgumentToParameter, Both }; - +enum class PackFold { ParameterToArgument, ArgumentToParameter }; static TemplateDeductionResult DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, ArrayRef<TemplateArgument> Ps, @@ -1713,21 +1711,7 @@ static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch( DeducedTemplateArgument Result = checkDeducedTemplateArguments(S.Context, Deduced[Index], NewDeduced); if (Result.isNull()) { - // We can also get inconsistencies when matching NTTP type. - switch (NamedDecl *Param = TemplateParams->getParam(Index); - Param->getKind()) { - case Decl::TemplateTypeParm: - Info.Param = cast<TemplateTypeParmDecl>(Param); - break; - case Decl::NonTypeTemplateParm: - Info.Param = cast<NonTypeTemplateParmDecl>(Param); - break; - case Decl::TemplateTemplateParm: - Info.Param = cast<TemplateTemplateParmDecl>(Param); - break; - default: - llvm_unreachable("unexpected kind"); - } + Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index)); Info.FirstArg = Deduced[Index]; Info.SecondArg = NewDeduced; return TemplateDeductionResult::Inconsistent; @@ -2565,31 +2549,8 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, if (const NonTypeTemplateParmDecl *NTTP = getDeducedParameterFromExpr(Info, P.getAsExpr())) { switch (A.getKind()) { - case TemplateArgument::Expression: { - const Expr *E = A.getAsExpr(); - // When checking NTTP, if either the parameter or the argument is - // dependent, as there would be otherwise nothing to deduce, we force - // the argument to the parameter type using this dependent implicit - // cast, in order to maintain invariants. Now we can deduce the - // resulting type from the original type, and deduce the original type - // against the parameter we are checking. - if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E); - ICE && ICE->getCastKind() == clang::CK_Dependent) { - E = ICE->getSubExpr(); - if (auto Result = DeduceTemplateArgumentsByTypeMatch( - S, TemplateParams, ICE->getType(), E->getType(), Info, - Deduced, TDF_SkipNonDependent, - PartialOrdering ? PartialOrderingKind::NonCall - : PartialOrderingKind::None, - /*DeducedFromArrayBound=*/false, HasDeducedAnyParam); - Result != TemplateDeductionResult::Success) - return Result; - } - return DeduceNonTypeTemplateArgument( - S, TemplateParams, NTTP, DeducedTemplateArgument(A), E->getType(), - Info, PartialOrdering, Deduced, HasDeducedAnyParam); - } case TemplateArgument::Integral: + case TemplateArgument::Expression: case TemplateArgument::StructuralValue: return DeduceNonTypeTemplateArgument( S, TemplateParams, NTTP, DeducedTemplateArgument(A), @@ -2678,75 +2639,50 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, SmallVectorImpl<DeducedTemplateArgument> &Deduced, bool NumberOfArgumentsMustMatch, bool PartialOrdering, PackFold PackFold, bool *HasDeducedAnyParam) { - bool FoldPackParameter = PackFold == PackFold::ParameterToArgument || - PackFold == PackFold::Both, - FoldPackArgument = PackFold == PackFold::ArgumentToParameter || - PackFold == PackFold::Both; - + if (PackFold == PackFold::ArgumentToParameter) + std::swap(Ps, As); // C++0x [temp.deduct.type]p9: // If the template argument list of P contains a pack expansion that is not // the last template argument, the entire template argument list is a // non-deduced context. - if (FoldPackParameter && hasPackExpansionBeforeEnd(Ps)) - return TemplateDeductionResult::Success; - - if (FoldPackArgument && hasPackExpansionBeforeEnd(As)) + if (hasPackExpansionBeforeEnd(Ps)) return TemplateDeductionResult::Success; // C++0x [temp.deduct.type]p9: // If P has a form that contains <T> or <i>, then each argument Pi of the // respective template argument list P is compared with the corresponding // argument Ai of the corresponding template argument list of A. - for (unsigned ArgIdx = 0, ParamIdx = 0; /**/; /**/) { - if (!hasTemplateArgumentForDeduction(Ps, ParamIdx)) - return !FoldPackParameter && hasTemplateArgumentForDeduction(As, ArgIdx) - ? TemplateDeductionResult::MiscellaneousDeductionFailure - : TemplateDeductionResult::Success; - - if (!Ps[ParamIdx].isPackExpansion()) { + unsigned ArgIdx = 0, ParamIdx = 0; + for (; hasTemplateArgumentForDeduction(Ps, ParamIdx); ++ParamIdx) { + const TemplateArgument &P = Ps[ParamIdx]; + if (!P.isPackExpansion()) { // The simple case: deduce template arguments by matching Pi and Ai. // Check whether we have enough arguments. if (!hasTemplateArgumentForDeduction(As, ArgIdx)) - return !FoldPackArgument && NumberOfArgumentsMustMatch + return NumberOfArgumentsMustMatch ? TemplateDeductionResult::MiscellaneousDeductionFailure : TemplateDeductionResult::Success; - if (As[ArgIdx].isPackExpansion()) { - // C++1z [temp.deduct.type]p9: - // During partial ordering, if Ai was originally a pack expansion - // [and] Pi is not a pack expansion, template argument deduction - // fails. - if (!FoldPackArgument) - return TemplateDeductionResult::MiscellaneousDeductionFailure; - - TemplateArgument Pattern = As[ArgIdx].getPackExpansionPattern(); - for (;;) { - // Deduce template parameters from the pattern. - if (auto Result = DeduceTemplateArguments( - S, TemplateParams, Ps[ParamIdx], Pattern, Info, - PartialOrdering, Deduced, HasDeducedAnyParam); - Result != TemplateDeductionResult::Success) - return Result; + // C++1z [temp.deduct.type]p9: + // During partial ordering, if Ai was originally a pack expansion [and] + // Pi is not a pack expansion, template argument deduction fails. + if (As[ArgIdx].isPackExpansion()) + return TemplateDeductionResult::MiscellaneousDeductionFailure; - ++ParamIdx; - if (!hasTemplateArgumentForDeduction(Ps, ParamIdx)) - return TemplateDeductionResult::Success; - if (Ps[ParamIdx].isPackExpansion()) - break; - } - } else { - // Perform deduction for this Pi/Ai pair. - if (auto Result = DeduceTemplateArguments( - S, TemplateParams, Ps[ParamIdx], As[ArgIdx], Info, - PartialOrdering, Deduced, HasDeducedAnyParam); - Result != TemplateDeductionResult::Success) - return Result; + // Perform deduction for this Pi/Ai pair. + TemplateArgument Pi = P, Ai = As[ArgIdx]; + if (PackFold == PackFold::ArgumentToParameter) + std::swap(Pi, Ai); + if (auto Result = DeduceTemplateArguments(S, TemplateParams, Pi, Ai, Info, + PartialOrdering, Deduced, + HasDeducedAnyParam); + Result != TemplateDeductionResult::Success) + return Result; - ++ArgIdx; - ++ParamIdx; - continue; - } + // Move to the next argument. + ++ArgIdx; + continue; } // The parameter is a pack expansion. @@ -2756,7 +2692,7 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, // each remaining argument in the template argument list of A. Each // comparison deduces template arguments for subsequent positions in the // template parameter packs expanded by Pi. - TemplateArgument Pattern = Ps[ParamIdx].getPackExpansionPattern(); + TemplateArgument Pattern = P.getPackExpansionPattern(); // Prepare to deduce the packs within the pattern. PackDeductionScope PackScope(S, TemplateParams, Deduced, Info, Pattern); @@ -2767,12 +2703,13 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, for (; hasTemplateArgumentForDeduction(As, ArgIdx) && PackScope.hasNextElement(); ++ArgIdx) { - if (!FoldPackParameter && !As[ArgIdx].isPackExpansion()) - return TemplateDeductionResult::MiscellaneousDeductionFailure; + TemplateArgument Pi = Pattern, Ai = As[ArgIdx]; + if (PackFold == PackFold::ArgumentToParameter) + std::swap(Pi, Ai); // Deduce template arguments from the pattern. - if (auto Result = DeduceTemplateArguments( - S, TemplateParams, Pattern, As[ArgIdx], Info, PartialOrdering, - Deduced, HasDeducedAnyParam); + if (auto Result = DeduceTemplateArguments(S, TemplateParams, Pi, Ai, Info, + PartialOrdering, Deduced, + HasDeducedAnyParam); Result != TemplateDeductionResult::Success) return Result; @@ -2781,8 +2718,12 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, // Build argument packs for each of the parameter packs expanded by this // pack expansion. - return PackScope.finish(); + if (auto Result = PackScope.finish(); + Result != TemplateDeductionResult::Success) + return Result; } + + return TemplateDeductionResult::Success; } TemplateDeductionResult Sema::DeduceTemplateArguments( @@ -3361,6 +3302,7 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction( // Unevaluated SFINAE context. EnterExpressionEvaluationContext Unevaluated( S, Sema::ExpressionEvaluationContext::Unevaluated); + Sema::SFINAETrap Trap(S); Sema::ContextRAII SavedContext(S, getAsDeclContextOrEnclosing(Template)); @@ -3378,36 +3320,20 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction( // Check that we produced the correct argument list. TemplateParameterList *TemplateParams = Template->getTemplateParameters(); - auto isSame = [&](unsigned I, const TemplateArgument &P, - const TemplateArgument &A) { - if (isSameTemplateArg(S.Context, P, A, PartialOrdering, - /*PackExpansionMatchesPack=*/true)) - return true; - Info.Param = makeTemplateParameter(TemplateParams->getParam(I)); - Info.FirstArg = P; - Info.SecondArg = A; - return false; - }; for (unsigned I = 0, E = TemplateParams->size(); I != E; ++I) { - const TemplateArgument &P = TemplateArgs[I]; - if (P.isPackExpansion()) { - assert(I == TemplateArgs.size() - 1); - for (/**/; I != E; ++I) { - const TemplateArgument &A = CanonicalBuilder[I]; - if (A.getKind() == TemplateArgument::Pack) { - for (const TemplateArgument &Ai : A.getPackAsArray()) - if (!isSame(I, P, Ai)) - return TemplateDeductionResult::NonDeducedMismatch; - } else if (!isSame(I, P, A)) { - return TemplateDeductionResult::NonDeducedMismatch; - } - } - break; - } - if (!isSame(I, P, CanonicalBuilder[I])) + TemplateArgument InstArg = CanonicalBuilder[I]; + if (!isSameTemplateArg(S.Context, TemplateArgs[I], InstArg, PartialOrdering, + /*PackExpansionMatchesPack=*/true)) { + Info.Param = makeTemplateParameter(TemplateParams->getParam(I)); + Info.FirstArg = TemplateArgs[I]; + Info.SecondArg = InstArg; return TemplateDeductionResult::NonDeducedMismatch; + } } + if (Trap.hasErrorOccurred()) + return TemplateDeductionResult::SubstitutionFailure; + if (!PartialOrdering) { if (auto Result = CheckDeducedArgumentConstraints( S, Template, SugaredBuilder, CanonicalBuilder, Info); @@ -3428,6 +3354,7 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction( // Unevaluated SFINAE context. EnterExpressionEvaluationContext Unevaluated( S, Sema::ExpressionEvaluationContext::Unevaluated); + Sema::SFINAETrap Trap(S); Sema::ContextRAII SavedContext(S, getAsDeclContextOrEnclosing(TD)); @@ -3436,13 +3363,20 @@ static TemplateDeductionResult FinishTemplateArgumentDeduction( // explicitly specified, template argument deduction fails. SmallVector<TemplateArgument, 4> SugaredBuilder, CanonicalBuilder; if (auto Result = ConvertDeducedTemplateArguments( - S, TD, /*IsDeduced=*/false, Deduced, Info, SugaredBuilder, + S, TD, /*IsPartialOrdering=*/false, Deduced, Info, SugaredBuilder, CanonicalBuilder); Result != TemplateDeductionResult::Success) return Result; - return ::CheckDeducedArgumentConstraints(S, TD, SugaredBuilder, - CanonicalBuilder, Info); + if (Trap.hasErrorOccurred()) + return TemplateDeductionResult::SubstitutionFailure; + + if (auto Result = CheckDeducedArgumentConstraints(S, TD, SugaredBuilder, + CanonicalBuilder, Info); + Result != TemplateDeductionResult::Success) + return Result; + + return TemplateDeductionResult::Success; } /// Perform template argument deduction to determine whether the given template @@ -3489,20 +3423,16 @@ DeduceTemplateArguments(Sema &S, T *Partial, if (Inst.isInvalid()) return TemplateDeductionResult::InstantiationDepth; + if (Trap.hasErrorOccurred()) + return TemplateDeductionResult::SubstitutionFailure; + TemplateDeductionResult Result; S.runWithSufficientStackSpace(Info.getLocation(), [&] { Result = ::FinishTemplateArgumentDeduction(S, Partial, /*IsPartialOrdering=*/false, TemplateArgs, Deduced, Info); }); - - if (Result != TemplateDeductionResult::Success) - return Result; - - if (Trap.hasErrorOccurred()) - return TemplateDeductionResult::SubstitutionFailure; - - return TemplateDeductionResult::Success; + return Result; } TemplateDeductionResult @@ -3558,18 +3488,14 @@ Sema::DeduceTemplateArgumentsFromType(TemplateDecl *TD, QualType FromType, if (Inst.isInvalid()) return TemplateDeductionResult::InstantiationDepth; + if (Trap.hasErrorOccurred()) + return TemplateDeductionResult::SubstitutionFailure; + TemplateDeductionResult Result; runWithSufficientStackSpace(Info.getLocation(), [&] { Result = ::FinishTemplateArgumentDeduction(*this, TD, Deduced, Info); }); - - if (Result != TemplateDeductionResult::Success) - return Result; - - if (Trap.hasErrorOccurred()) - return TemplateDeductionResult::SubstitutionFailure; - - return TemplateDeductionResult::Success; + return Result; } /// Determine whether the given type T is a simple-template-id type. @@ -6210,23 +6136,14 @@ static bool isAtLeastAsSpecializedAs(Sema &S, QualType T1, QualType T2, return false; const auto *TST1 = cast<TemplateSpecializationType>(T1); - - Sema::SFINAETrap Trap(S); - - TemplateDeductionResult Result; + bool AtLeastAsSpecialized; S.runWithSufficientStackSpace(Info.getLocation(), [&] { - Result = ::FinishTemplateArgumentDeduction( - S, P2, /*IsPartialOrdering=*/true, TST1->template_arguments(), Deduced, - Info); + AtLeastAsSpecialized = + FinishTemplateArgumentDeduction( + S, P2, /*IsPartialOrdering=*/true, TST1->template_arguments(), + Deduced, Info) == TemplateDeductionResult::Success; }); - - if (Result != TemplateDeductionResult::Success) - return false; - - if (Trap.hasErrorOccurred()) - return false; - - return true; + return AtLeastAsSpecialized; } namespace { @@ -6464,9 +6381,8 @@ bool Sema::isMoreSpecializedThanPrimary( } bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs( - TemplateParameterList *P, TemplateDecl *PArg, TemplateDecl *AArg, - const DefaultArguments &DefaultArgs, SourceLocation ArgLoc, - bool IsDeduced) { + TemplateParameterList *P, TemplateDecl *AArg, + const DefaultArguments &DefaultArgs, SourceLocation Loc, bool IsDeduced) { // C++1z [temp.arg.template]p4: (DR 150) // A template template-parameter P is at least as specialized as a // template template-argument A if, given the following rewrite to two @@ -6478,12 +6394,6 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs( // TemplateParameterList *A = AArg->getTemplateParameters(); - Sema::InstantiatingTemplate Inst( - *this, ArgLoc, Sema::InstantiatingTemplate::PartialOrderingTTP(), PArg, - SourceRange(P->getTemplateLoc(), P->getRAngleLoc())); - if (Inst.isInvalid()) - return false; - // Given an invented class template X with the template parameter list of // A (including default arguments): // - Each function template has a single function parameter whose type is @@ -6498,6 +6408,8 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs( // templates. SmallVector<TemplateArgument, 4> PArgs; { + SFINAETrap Trap(*this); + Context.getInjectedTemplateArgs(P, PArgs); TemplateArgumentListInfo PArgList(P->getLAngleLoc(), P->getRAngleLoc()); @@ -6517,17 +6429,18 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs( // C++1z [temp.arg.template]p3: // If the rewrite produces an invalid type, then P is not at least as // specialized as A. - SmallVector<TemplateArgument, 4> CanonicalPArgs; - if (CheckTemplateArgumentList(AArg, ArgLoc, PArgList, DefaultArgs, false, - PArgs, CanonicalPArgs, + SmallVector<TemplateArgument, 4> SugaredPArgs; + if (CheckTemplateArgumentList(AArg, Loc, PArgList, DefaultArgs, false, + SugaredPArgs, PArgs, /*UpdateArgsWithConversions=*/true, /*ConstraintsNotSatisfied=*/nullptr, - /*PartialOrderingTTP=*/true)) + /*PartialOrderTTP=*/true) || + Trap.hasErrorOccurred()) return false; } // Determine whether P1 is at least as specialized as P2. - TemplateDeductionInfo Info(ArgLoc, A->getDepth()); + TemplateDeductionInfo Info(Loc, A->getDepth()); SmallVector<DeducedTemplateArgument, 4> Deduced; Deduced.resize(A->size()); @@ -6542,89 +6455,29 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs( // be inverted between Ps and As. On non-deduced context, matching needs to // happen both ways, according to [temp.arg.template]p3, but this is // currently implemented as a special case elsewhere. - switch (::DeduceTemplateArguments( - *this, A, AArgs, PArgs, Info, Deduced, - /*NumberOfArgumentsMustMatch=*/false, /*PartialOrdering=*/true, - IsDeduced ? PackFold::ArgumentToParameter : PackFold::Both, - /*HasDeducedAnyParam=*/nullptr)) { - case clang::TemplateDeductionResult::Success: - break; - - case TemplateDeductionResult::MiscellaneousDeductionFailure: - Diag(AArg->getLocation(), diag::err_template_param_list_ diff erent_arity) - << (A->size() > P->size()) << /*isTemplateTemplateParameter=*/true - << SourceRange(A->getTemplateLoc(), P->getRAngleLoc()); - return false; - case TemplateDeductionResult::NonDeducedMismatch: - Diag(AArg->getLocation(), diag::err_non_deduced_mismatch) - << Info.FirstArg << Info.SecondArg; + if (::DeduceTemplateArguments(*this, A, AArgs, PArgs, Info, Deduced, + /*NumberOfArgumentsMustMatch=*/false, + /*PartialOrdering=*/true, + IsDeduced ? PackFold::ArgumentToParameter + : PackFold::ParameterToArgument, + /*HasDeducedAnyParam=*/nullptr) != + TemplateDeductionResult::Success) return false; - case TemplateDeductionResult::Inconsistent: - Diag(getAsNamedDecl(Info.Param)->getLocation(), - diag::err_inconsistent_deduction) - << Info.FirstArg << Info.SecondArg; - return false; - case TemplateDeductionResult::AlreadyDiagnosed: - return false; - - // None of these should happen for a plain deduction. - case TemplateDeductionResult::Invalid: - case TemplateDeductionResult::InstantiationDepth: - case TemplateDeductionResult::Incomplete: - case TemplateDeductionResult::IncompletePack: - case TemplateDeductionResult::Underqualified: - case TemplateDeductionResult::SubstitutionFailure: - case TemplateDeductionResult::DeducedMismatch: - case TemplateDeductionResult::DeducedMismatchNested: - case TemplateDeductionResult::TooManyArguments: - case TemplateDeductionResult::TooFewArguments: - case TemplateDeductionResult::InvalidExplicitArguments: - case TemplateDeductionResult::NonDependentConversionFailure: - case TemplateDeductionResult::ConstraintsNotSatisfied: - case TemplateDeductionResult::CUDATargetMismatch: - llvm_unreachable("Unexpected Result"); - } SmallVector<TemplateArgument, 4> DeducedArgs(Deduced.begin(), Deduced.end()); + Sema::InstantiatingTemplate Inst(*this, Info.getLocation(), AArg, DeducedArgs, + Info); + if (Inst.isInvalid()) + return false; - TemplateDeductionResult TDK; + bool AtLeastAsSpecialized; runWithSufficientStackSpace(Info.getLocation(), [&] { - TDK = ::FinishTemplateArgumentDeduction( - *this, AArg, /*IsPartialOrdering=*/true, PArgs, Deduced, Info); + AtLeastAsSpecialized = + ::FinishTemplateArgumentDeduction( + *this, AArg, /*IsPartialOrdering=*/true, PArgs, Deduced, Info) == + TemplateDeductionResult::Success; }); - switch (TDK) { - case TemplateDeductionResult::Success: - return true; - - // It doesn't seem possible to get a non-deduced mismatch when partial - // ordering TTPs. - case TemplateDeductionResult::NonDeducedMismatch: - llvm_unreachable("Unexpected NonDeducedMismatch"); - - // Substitution failures should have already been diagnosed. - case TemplateDeductionResult::AlreadyDiagnosed: - case TemplateDeductionResult::SubstitutionFailure: - case TemplateDeductionResult::InstantiationDepth: - return false; - - // None of these should happen when just converting deduced arguments. - case TemplateDeductionResult::Invalid: - case TemplateDeductionResult::Incomplete: - case TemplateDeductionResult::IncompletePack: - case TemplateDeductionResult::Inconsistent: - case TemplateDeductionResult::Underqualified: - case TemplateDeductionResult::DeducedMismatch: - case TemplateDeductionResult::DeducedMismatchNested: - case TemplateDeductionResult::TooManyArguments: - case TemplateDeductionResult::TooFewArguments: - case TemplateDeductionResult::InvalidExplicitArguments: - case TemplateDeductionResult::NonDependentConversionFailure: - case TemplateDeductionResult::ConstraintsNotSatisfied: - case TemplateDeductionResult::MiscellaneousDeductionFailure: - case TemplateDeductionResult::CUDATargetMismatch: - llvm_unreachable("Unexpected Result"); - } - llvm_unreachable("Unexpected TDK"); + return AtLeastAsSpecialized; } namespace { diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index de71774bd8e559..2263b76520ca25 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -572,7 +572,6 @@ bool Sema::CodeSynthesisContext::isInstantiationRecord() const { case LambdaExpressionSubstitution: case BuildingDeductionGuides: case TypeAliasTemplateInstantiation: - case PartialOrderingTTP: return false; // This function should never be called when Kind's value is Memoization. @@ -805,11 +804,6 @@ Sema::InstantiatingTemplate::InstantiatingTemplate( SemaRef, CodeSynthesisContext::BuildingDeductionGuides, PointOfInstantiation, InstantiationRange, Entity) {} -Sema::InstantiatingTemplate::InstantiatingTemplate( - Sema &SemaRef, SourceLocation ArgLoc, PartialOrderingTTP, - TemplateDecl *PArg, SourceRange InstantiationRange) - : InstantiatingTemplate(SemaRef, CodeSynthesisContext::PartialOrderingTTP, - ArgLoc, InstantiationRange, PArg) {} void Sema::pushCodeSynthesisContext(CodeSynthesisContext Ctx) { Ctx.SavedInNonInstantiationSFINAEContext = InNonInstantiationSFINAEContext; @@ -1249,14 +1243,6 @@ void Sema::PrintInstantiationStack() { << cast<TypeAliasTemplateDecl>(Active->Entity) << Active->InstantiationRange; break; - case CodeSynthesisContext::PartialOrderingTTP: - Diags.Report(Active->PointOfInstantiation, - diag::note_template_arg_template_params_mismatch); - if (SourceLocation ParamLoc = Active->Entity->getLocation(); - ParamLoc.isValid()) - Diags.Report(ParamLoc, diag::note_template_prev_declaration) - << /*isTemplateTemplateParam=*/true << Active->InstantiationRange; - break; } } } @@ -1299,7 +1285,6 @@ std::optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const { case CodeSynthesisContext::PriorTemplateArgumentSubstitution: case CodeSynthesisContext::DefaultTemplateArgumentChecking: case CodeSynthesisContext::RewritingOperatorAsSpaceship: - case CodeSynthesisContext::PartialOrderingTTP: // A default template argument instantiation and substitution into // template parameters with arguments for prior parameters may or may // not be a SFINAE context; look further up the stack. diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp index 1bbbd1d3429ddd..19793fe8263726 100644 --- a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp +++ b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp @@ -2,13 +2,13 @@ template <class T> struct eval; // expected-note 3{{template is declared here}} -template <template <class, class...> class TT, class T1, class... Rest> +template <template <class, class...> class TT, class T1, class... Rest> struct eval<TT<T1, Rest...>> { }; -template <class T1> struct A; -template <class T1, class T2> struct B; -template <int N> struct C; -template <class T1, int N> struct D; +template <class T1> struct A; +template <class T1, class T2> struct B; +template <int N> struct C; +template <class T1, int N> struct D; template <class T1, class T2, int N = 17> struct E; eval<A<int>> eA; @@ -17,32 +17,27 @@ eval<C<17>> eC; // expected-error{{implicit instantiation of undefined template eval<D<int, 17>> eD; // expected-error{{implicit instantiation of undefined template 'eval<D<int, 17>>'}} eval<E<int, float>> eE; // expected-error{{implicit instantiation of undefined template 'eval<E<int, float>>}} -template< - template <int ...N> // expected-error{{deduced non-type template argument does not have the same type as the corresponding template parameter ('int' vs 'long')}} - class TT // expected-note {{previous template template parameter is here}} -> struct X0 { }; - +template<template <int ...N> class TT> struct X0 { }; // expected-note{{previous non-type template parameter with type 'int' is here}} template<int I, int J, int ...Rest> struct X0a; template<int ...Rest> struct X0b; -template<int I, long J> struct X0c; // expected-note{{template parameter is declared here}} +template<int I, long J> struct X0c; // expected-note{{template non-type parameter has a diff erent type 'long' in template argument}} X0<X0a> inst_x0a; X0<X0b> inst_x0b; -X0<X0c> inst_x0c; // expected-note{{template template argument has diff erent template parameters than its corresponding template template parameter}} +X0<X0c> inst_x0c; // expected-error{{template template argument has diff erent template parameters than its corresponding template template parameter}} -template<typename T, - template <T ...N> // expected-error{{deduced non-type template argument does not have the same type as the corresponding template parameter ('short' vs 'long')}} - class TT // expected-note {{previous template template parameter is here}} -> struct X1 { }; +template<typename T, + template <T ...N> class TT> // expected-note{{previous non-type template parameter with type 'short' is here}} +struct X1 { }; template<int I, int J, int ...Rest> struct X1a; template<long I, long ...Rest> struct X1b; template<short I, short J> struct X1c; -template<short I, long J> struct X1d; // expected-note{{template parameter is declared here}} +template<short I, long J> struct X1d; // expected-note{{template non-type parameter has a diff erent type 'long' in template argument}} X1<int, X1a> inst_x1a; X1<long, X1b> inst_x1b; X1<short, X1c> inst_x1c; -X1<short, X1d> inst_x1d; // expected-note{{template template argument has diff erent template parameters than its corresponding template template parameter}} +X1<short, X1d> inst_x1d; // expected-error{{template template argument has diff erent template parameters than its corresponding template template paramete}} template <int> class X2; // expected-note{{template is declared here}} \ // expected-note{{template is declared here}} diff --git a/clang/test/CXX/temp/temp.param/p12.cpp b/clang/test/CXX/temp/temp.param/p12.cpp index 8317e7f24152cc..7be38790905fa3 100644 --- a/clang/test/CXX/temp/temp.param/p12.cpp +++ b/clang/test/CXX/temp/temp.param/p12.cpp @@ -1,40 +1,39 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s -template<typename> struct Y1; // expected-note{{template is declared here}} +// RUN: %clang_cc1 -fsyntax-only -verify %s +template<typename> struct Y1; // expected-note{{too few template parameters in template template argument}} template<typename, int> struct Y2; // C++ [temp.param]p12: -template<class T1, +template<class T1, class T2 = int> // expected-note{{previous default template argument defined here}} class B3; template<class T1, typename T2> class B3; -template<class T1, +template<class T1, typename T2 = float> // expected-error{{template parameter redefines default argument}} class B3; -template<template<class, int> class, +template<template<class, int> class, template<class> class = Y1> // expected-note{{previous default template argument defined here}} class B3t; template<template<class, int> class, template<class> class> class B3t; -template<template<class, int> class, +template<template<class, int> class, template<class> class = Y1> // expected-error{{template parameter redefines default argument}} class B3t; -template<int N, +template<int N, int M = 5> // expected-note{{previous default template argument defined here}} class B3n; template<int N, int M> class B3n; -template<int N, +template<int N, int M = 7> // expected-error{{template parameter redefines default argument}} class B3n; // Check validity of default arguments -template<template<class, int> class =// expected-note {{previous template template parameter is here}} - Y1> // expected-error{{too many template arguments for class template 'Y1'}} - // expected-note@-1 {{template template argument has diff erent template parameters than its corresponding template template parameter}} +template<template<class, int> class // expected-note{{previous template template parameter is here}} + = Y1> // expected-error{{template template argument has diff erent template parameters than its corresponding template template parameter}} class C1 {}; C1<> c1; // expected-note{{while checking a default template argument}} diff --git a/clang/test/Modules/cxx-templates.cpp b/clang/test/Modules/cxx-templates.cpp index 953fc0d9e867c4..b7d5741e69af61 100644 --- a/clang/test/Modules/cxx-templates.cpp +++ b/clang/test/Modules/cxx-templates.cpp @@ -40,14 +40,23 @@ void g() { template_param_kinds_1<0>(); // ok, from cxx-templates-a.h template_param_kinds_1<int>(); // ok, from cxx-templates-b.h - template_param_kinds_2<Tmpl_T_C>(); // ok, from cxx-templates-b.h + + template_param_kinds_2<Tmpl_T_C>(); // expected-error {{no matching function}} + // expected-note@Inputs/cxx-templates-a.h:11 {{invalid explicitly-specified argument}} + // expected-note@Inputs/cxx-templates-b.h:11 {{invalid explicitly-specified argument}} template_param_kinds_2<Tmpl_T_I_I>(); // expected-error {{ambiguous}} // expected-note@Inputs/cxx-templates-a.h:11 {{candidate}} // expected-note@Inputs/cxx-templates-b.h:11 {{candidate}} - template_param_kinds_3<Tmpl_T_T_A>(); - template_param_kinds_3<Tmpl_T_T_B>(); + // FIXME: This should be valid, but we incorrectly match the template template + // argument against both template template parameters. + template_param_kinds_3<Tmpl_T_T_A>(); // expected-error {{ambiguous}} + // expected-note@Inputs/cxx-templates-a.h:12 {{candidate}} + // expected-note@Inputs/cxx-templates-b.h:12 {{candidate}} + template_param_kinds_3<Tmpl_T_T_B>(); // expected-error {{ambiguous}} + // expected-note@Inputs/cxx-templates-a.h:12 {{candidate}} + // expected-note@Inputs/cxx-templates-b.h:12 {{candidate}} // Trigger the instantiation of a template in 'a' that uses a type defined in // 'common'. That type is not visible here. diff --git a/clang/test/SemaCXX/make_integer_seq.cpp b/clang/test/SemaCXX/make_integer_seq.cpp index 71b7b8260d4abc..8f72ce15eef476 100644 --- a/clang/test/SemaCXX/make_integer_seq.cpp +++ b/clang/test/SemaCXX/make_integer_seq.cpp @@ -48,5 +48,6 @@ using illformed2 = ErrorSeq<int, -5>; // expected-note{{in instantiation}} template <typename T, T N> void f() {} __make_integer_seq<f, int, 0> x; // expected-error{{template template parameter must be a class template or type alias template}} -__make_integer_seq<__make_integer_seq, int, 10> PR28494; // expected-note{{ diff erent template parameters}} -// expected-error@make_integer_seq.cpp:* {{template argument for template template parameter must be a class template or type alias template}} +__make_integer_seq<__make_integer_seq, int, 10> PR28494; // expected-error{{ diff erent template parameters}} +// expected-note@make_integer_seq.cpp:* {{template parameter has a diff erent kind}} +// expected-note@make_integer_seq.cpp:* {{previous template template parameter is here}} diff --git a/clang/test/SemaTemplate/cwg2398.cpp b/clang/test/SemaTemplate/cwg2398.cpp index b9e9e9f0c97f26..6dc7af6ea17899 100644 --- a/clang/test/SemaTemplate/cwg2398.cpp +++ b/clang/test/SemaTemplate/cwg2398.cpp @@ -106,10 +106,12 @@ namespace type_pack3 { template<class T3> struct B; template<template<class T4 > class TT1, class T5 > struct B<TT1<T5 >>; - - template<template<class T6, class ...T7s> class TT2, class T8, class ...T9s> struct B<TT2<T8, T9s...>> {}; + // new-note@-1 {{template is declared here}} + template<template<class T6, class ...T7s> class TT2, class T8, class ...T9s> struct B<TT2<T8, T9s...>>; + // old-note@-1 {{template is declared here}} template struct B<A<int>>; + // expected-error@-1 {{explicit instantiation of undefined template}} } // namespace type_pack3 namespace gcc_issue { @@ -362,73 +364,6 @@ namespace classes { } // namespace defaulted } // namespace classes -namespace packs { - namespace t1 { - // FIXME: This should be rejected - template<template<int, int...> class> struct A {}; - // old-note@-1 {{previous non-type template parameter with type 'int' is here}} - - template<char> struct B; - // old-note@-1 {{template non-type parameter has a diff erent type 'char' in template argument}} - - template struct A<B>; - // old-error@-1 {{has diff erent template parameters}} - } // namespace t1 - namespace t2 { - template<template<char, int...> class> struct A {}; - // old-note@-1 {{previous non-type template parameter with type 'char' is here}} - - template<int> struct B; - // old-note@-1 {{template non-type parameter has a diff erent type 'int' in template argument}} - - template struct A<B>; - // old-error@-1 {{has diff erent template parameters}} - } // namespace t2 - namespace t3 { - // FIXME: This should be rejected - template<template<int...> class> struct A {}; - // old-note@-1 {{previous non-type template parameter with type 'int' is here}} - - template<char> struct B; - // old-note@-1 {{template non-type parameter has a diff erent type 'char' in template argument}} - - template struct A<B>; - // old-error@-1 {{has diff erent template parameters}} - } // namespace t3 - namespace t4 { - template<template<char...> class> struct A {}; - // old-note@-1 {{previous non-type template parameter with type 'char' is here}} - - template<int> struct B; - // old-note@-1 {{template non-type parameter has a diff erent type 'int' in template argument}} - - template struct A<B>; - // old-error@-1 {{has diff erent template parameters}} - } // namespace t4 -} // namespace packs - -namespace partial { - namespace t1 { - template<template<class... T1s> class TT1> struct A {}; - - template<template<class T2> class TT2> struct A<TT2>; - // new-note@-1 {{template is declared here}} - - template<class... T3s> struct B; - template struct A<B>; - // new-error@-1 {{explicit instantiation of undefined template}} - } // namespace t1 - namespace t2 { - template<template<class... T1s> class TT1> struct A; - - template<template<class T2> class TT2> struct A<TT2> {}; - - template<class T3> struct B; - template struct A<B>; - } // namespace t1 - -} // namespace partial - namespace regression1 { template <typename T, typename Y> struct map {}; template <typename T> class foo {}; @@ -445,93 +380,6 @@ namespace regression1 { } } // namespace regression1 -namespace constraints { - template <class T> concept C1 = true; - // new-note@-1 {{similar constraint expression here}} - // new-note@-2 2{{similar constraint expressions not considered equivalent}} - - template <class T> concept C2 = C1<T> && true; - // new-note@-1 2{{similar constraint expression here}} - - template <class T> concept D1 = true; - // new-note@-1 {{similar constraint expressions not considered equivalent}} - - namespace t1 { - template<template<C1, class... T1s> class TT1> // new-note {{TT1' declared here}} - struct A {}; - template<D1, class T2> struct B {}; // new-note {{'B' declared here}} - template struct A<B>; - // new-error@-1 {{'B' is more constrained than template template parameter 'TT1'}} - } // namespace t1 - namespace t2 { - template<template<C2, class... T1s> class TT1> struct A {}; - template<C1, class T2> struct B {}; - template struct A<B>; - } // namespace t2 - namespace t3 { - template<template<C1, class... T1s> class TT1> // new-note {{'TT1' declared here}} - struct A {}; - template<C2, class T2> struct B {}; // new-note {{'B' declared here}} - template struct A<B>; - // new-error@-1 {{'B' is more constrained than template template parameter 'TT1'}} - } // namespace t2 - namespace t4 { - // FIXME: This should be accepted. - template<template<C1... T1s> class TT1> // new-note {{'TT1' declared here}} - struct A {}; - template<C1 T2> struct B {}; // new-note {{'B' declared here}} - template struct A<B>; - // new-error@-1 {{'B' is more constrained than template template parameter 'TT1'}} - } // namespace t4 - namespace t5 { - // FIXME: This should be accepted - template<template<C2... T1s> class TT1> // new-note {{'TT1' declared here}} - struct A {}; - template<C1 T2> struct B {}; // new-note {{'B' declared here}} - template struct A<B>; - // new-error@-1 {{'B' is more constrained than template template parameter 'TT1'}} - } // namespace t5 - namespace t6 { - template<template<C1... T1s> class TT1> // new-note {{'TT1' declared here}} - struct A {}; - template<C2 T2> struct B {}; // new-note {{'B' declared here}} - template struct A<B>; - // new-error@-1 {{'B' is more constrained than template template parameter 'TT1'}} - } // namespace t6 - namespace t7 { - template<template<class... T1s> class TT1> - struct A {}; - template<C1 T2> struct B {}; - template struct A<B>; - } // namespace t7 - namespace t8 { - template<template<C1... T1s> class TT1> - struct A {}; - template<class T2> struct B {}; - template struct A<B>; - } // namespace t8 - namespace t9 { - template<template<C1... T1s> class TT1> // new-note {{'TT1' declared here}} - struct A {}; - template<D1 T2> struct B {}; // new-note {{'B' declared here}} - template struct A<B>; - // new-error@-1 {{'B' is more constrained than template template parameter 'TT1'}} - } // namespace t9 - namespace t10 { - template<template<class...> requires C1<int> class TT1> // new-note {{'TT1' declared here}} - struct A {}; - - template<class> requires C2<int> struct B {}; // new-note {{'B' declared here}} - template struct A<B>; - // new-error@-1 {{'B' is more constrained than template template parameter 'TT1'}} - } // namespace t10 - namespace t11 { - template<template<class...> requires C2<int> class TT1> struct A {}; - template<class> requires C1<int> struct B {}; - template struct A<B>; - } // namespace t11 -} // namespace constraints - namespace regression2 { template <class> struct D {}; diff --git a/clang/test/SemaTemplate/temp_arg_nontype.cpp b/clang/test/SemaTemplate/temp_arg_nontype.cpp index 8b270b22a12b46..f360aa14950edd 100644 --- a/clang/test/SemaTemplate/temp_arg_nontype.cpp +++ b/clang/test/SemaTemplate/temp_arg_nontype.cpp @@ -387,11 +387,12 @@ namespace PR17696 { namespace partial_order_ diff erent_types { template<int, int, typename T, typename, T> struct A; - // expected-note@-1 {{template is declared here}} - template<int N, typename T, typename U, T V> struct A<0, N, T, U, V> {}; - template<int N, typename T, typename U, U V> struct A<0, N, T, U, V>; - // expected-error@-1 {{class template partial specialization is not more specialized than the primary template}} - A<0, 0, int, int, 0> a; + template<int N, typename T, typename U, T V> struct A<0, N, T, U, V>; // expected-note {{matches}} + // FIXME: It appears that this partial specialization should be ill-formed as + // it is not more specialized than the primary template. V is not deducible + // because it does not have the same type as the corresponding parameter. + template<int N, typename T, typename U, U V> struct A<0, N, T, U, V> {}; // expected-note {{matches}} + A<0, 0, int, int, 0> a; // expected-error {{ambiguous}} } namespace partial_order_references { @@ -457,24 +458,13 @@ namespace dependent_nested_partial_specialization { namespace nondependent_default_arg_ordering { int n, m; template<typename A, A B = &n> struct X {}; - template<typename A> void f(X<A>); - // expected-note@-1 {{candidate function}} template<typename A> void f(X<A, &m>); - // expected-note@-1 {{candidate function}} template<typename A, A B> void f(X<A, B>); - // expected-note@-1 2{{candidate function}} template<template<typename U, U> class T, typename A, int *B> void f(T<A, B>); - // expected-note@-1 2{{candidate function}} - - // FIXME: When partial ordering, we get an inconsistent deduction between - // `A` (type-parameter-0-0) and `int *`, when deducing the first parameter. - // The deduction mechanism needs to be extended to be able to correctly - // handle these cases where the argument's template parameters appear in - // the result. void g() { - X<int *, &n> x; f(x); // expected-error {{call to 'f' is ambiguous}} - X<int *, &m> y; f(y); // expected-error {{call to 'f' is ambiguous}} + X<int *, &n> x; f(x); + X<int *, &m> y; f(y); } } diff --git a/clang/test/SemaTemplate/temp_arg_template.cpp b/clang/test/SemaTemplate/temp_arg_template.cpp index 9908af5e78669d..a7236669276aa3 100644 --- a/clang/test/SemaTemplate/temp_arg_template.cpp +++ b/clang/test/SemaTemplate/temp_arg_template.cpp @@ -1,40 +1,33 @@ // RUN: %clang_cc1 -fsyntax-only -verify=expected,precxx17 %std_cxx98-14 %s // RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx17 -std=c++17 %s -template<template<typename T> class X> struct A; // #A -// expected-note@-1 2{{previous template template parameter is here}} +template<template<typename T> class X> struct A; // expected-note 2{{previous template template parameter is here}} template<template<typename T, int I> class X> struct B; // expected-note{{previous template template parameter is here}} -template<template<int I> class X> struct C; -// precxx17-error@-1 {{deduced non-type template argument does not have the same type as the corresponding template parameter ('int' vs 'const int &')}} -// cxx17-error@-2 {{conversion from 'int' to 'const int &' in converted constant expression would bind reference to a temporary}} -// expected-note@-3 {{previous template template parameter is here}} +template<template<int I> class X> struct C; // expected-note {{previous non-type template parameter with type 'int' is here}} -template<class> struct X; // expected-note {{template is declared here}} -template<int N> struct Y; // expected-note {{template parameter is declared here}} +template<class> struct X; // expected-note{{too few template parameters in template template argument}} +template<int N> struct Y; // expected-note{{template parameter has a diff erent kind in template argument}} template<long N> struct Ylong; -template<const int &N> struct Yref; // precxx17-note {{template parameter is declared here}} +template<const int &N> struct Yref; // expected-note{{template non-type parameter has a diff erent type 'const int &' in template argument}} namespace N { template<class> struct Z; } -template<class, class> struct TooMany; // expected-note{{template is declared here}} +template<class, class> struct TooMany; // expected-note{{too many template parameters in template template argument}} A<X> *a1; A<N::Z> *a2; A< ::N::Z> *a3; -A<Y> *a4; // expected-error@#A {{template argument for non-type template parameter must be an expression}} - // expected-note@-1 {{ diff erent template parameters}} -A<TooMany> *a5; // expected-error {{too few template arguments for class template 'TooMany'}} - // expected-note@-1 {{ diff erent template parameters}} -B<X> *a6; // expected-error {{too many template arguments for class template 'X'}} - // expected-note@-1 {{ diff erent template parameters}} +A<Y> *a4; // expected-error{{template template argument has diff erent template parameters than its corresponding template template parameter}} +A<TooMany> *a5; // expected-error{{template template argument has diff erent template parameters than its corresponding template template parameter}} +B<X> *a6; // expected-error{{template template argument has diff erent template parameters than its corresponding template template parameter}} C<Y> *a7; C<Ylong> *a8; -C<Yref> *a9; // expected-note {{ diff erent template parameters}} +C<Yref> *a9; // expected-error{{template template argument has diff erent template parameters than its corresponding template template parameter}} template<typename T> void f(int); @@ -110,9 +103,9 @@ void foo() { namespace CheckDependentNonTypeParamTypes { template<template<typename T, typename U, T v> class X> struct A { - // expected-note@-1 {{previous template template parameter is here}} void f() { - X<int, void*, 3> x; + X<int, void*, 3> x; // precxx17-error {{does not refer to any declaration}} \ + cxx17-error {{value of type 'int' is not implicitly convertible to 'void *'}} } void g() { X<int, long, 3> x; @@ -131,16 +124,15 @@ namespace CheckDependentNonTypeParamTypes { } }; - template<typename T, typename U, U v> struct B { - // expected-error@-1 {{conflicting deduction 'U' against 'T' for parameter}} + template<typename T, typename U, U v> struct B { // precxx17-note {{parameter}} static const U value = v; }; // FIXME: This should probably be rejected, but the rules are at best unclear. - A<B> ab; // expected-note {{ diff erent template parameters}} + A<B> ab; void use() { - ab.f(); + ab.f(); // expected-note {{instantiation of}} ab.g(); ab.h(); } diff --git a/clang/test/SemaTemplate/temp_arg_template_p0522.cpp b/clang/test/SemaTemplate/temp_arg_template_p0522.cpp index d40577d5270468..6f6568b9ab7764 100644 --- a/clang/test/SemaTemplate/temp_arg_template_p0522.cpp +++ b/clang/test/SemaTemplate/temp_arg_template_p0522.cpp @@ -1,16 +1,14 @@ // RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s -// expected-note@temp_arg_template_p0522.cpp:* 1+{{template is declared here}} -// expected-note@temp_arg_template_p0522.cpp:* 1+{{template parameter is declared here}} -// expected-note@temp_arg_template_p0522.cpp:* 1+{{previous template template parameter is here}} +// expected-note@temp_arg_template_p0522.cpp:* 1+{{}} -template<template<int> typename> struct Ti; // #Ti -template<template<int...> typename> struct TPi; // #TPi +template<template<int> typename> struct Ti; +template<template<int...> typename> struct TPi; template<template<int, int...> typename> struct TiPi; template<template<int..., int...> typename> struct TPiPi; // FIXME: Why is this not ill-formed? -template<typename T, template<T> typename> struct tT0; // #tT0 -template<template<typename T, T> typename> struct Tt0; // #Tt0 +template<typename T, template<T> typename> struct tT0; +template<template<typename T, T> typename> struct Tt0; template<template<typename> typename> struct Tt; template<template<typename, typename...> typename> struct TtPt; @@ -21,8 +19,8 @@ template<int, int> struct ii; template<int...> struct Pi; template<int, int, int...> struct iiPi; -template<int, typename = int> struct iDt; // #iDt -template<int, typename> struct it; // #it +template<int, typename = int> struct iDt; +template<int, typename> struct it; template<typename T, T v> struct t0; @@ -33,14 +31,10 @@ namespace IntParam { Ti<iDi>, Ti<Pi>, Ti<iDt>>; - using err1 = Ti<ii>; // expected-error {{too few template arguments for class template 'ii'}} - // expected-note@-1 {{ diff erent template parameters}} - using err2 = Ti<iiPi>; // expected-error {{too few template arguments for class template 'iiPi'}} - // expected-note@-1 {{ diff erent template parameters}} - using err3 = Ti<t0>; // expected-error@#Ti {{template argument for template type parameter must be a type}} - // expected-note@-1 {{ diff erent template parameters}} - using err4 = Ti<it>; // expected-error {{too few template arguments for class template 'it'}} - // expected-note@-1 {{ diff erent template parameters}} + using err1 = Ti<ii>; // expected-error {{ diff erent template parameters}} + using err2 = Ti<iiPi>; // expected-error {{ diff erent template parameters}} + using err3 = Ti<t0>; // expected-error {{ diff erent template parameters}} + using err4 = Ti<it>; // expected-error {{ diff erent template parameters}} } // These are accepted by the backwards-compatibility "parameter pack in @@ -48,12 +42,9 @@ namespace IntParam { namespace IntPackParam { using ok = TPi<Pi>; using ok_compat = Pt<TPi<i>, TPi<iDi>, TPi<ii>, TPi<iiPi>>; - using err1 = TPi<t0>; // expected-error@#TPi {{template argument for template type parameter must be a type}} - // expected-note@-1 {{ diff erent template parameters}} - using err2 = TPi<iDt>; // expected-error@#iDt {{could not match 'type-parameter-0-1' against}} - // expected-note@-1 {{ diff erent template parameters}} - using err3 = TPi<it>; // expected-error@#it {{could not match 'type-parameter-0-1' against}} - // expected-note@-1 {{ diff erent template parameters}} + using err1 = TPi<t0>; // expected-error {{ diff erent template parameters}} + using err2 = TPi<iDt>; // expected-error {{ diff erent template parameters}} + using err3 = TPi<it>; // expected-error {{ diff erent template parameters}} } namespace IntAndPackParam { @@ -64,50 +55,42 @@ namespace IntAndPackParam { namespace DependentType { using ok = Pt<tT0<int, i>, tT0<int, iDi>>; - using err1 = tT0<int, ii>; // expected-error {{too few template arguments for class template 'ii'}} - // expected-note@-1 {{ diff erent template parameters}} + using err1 = tT0<int, ii>; // expected-error {{ diff erent template parameters}} using err2 = tT0<short, i>; // FIXME: should this be OK? using err2a = tT0<long long, i>; // FIXME: should this be OK (if long long is larger than int)? - using err2b = tT0<void*, i>; // expected-error@#tT0 {{value of type 'void *' is not implicitly convertible to 'int'}} - // expected-note@-1 {{ diff erent template parameters}} - using err3 = tT0<short, t0>; // expected-error@#tT0 {{template argument for template type parameter must be a type}} - // expected-note@-1 {{ diff erent template parameters}} + using err2b = tT0<void*, i>; // expected-error {{ diff erent template parameters}} + using err3 = tT0<short, t0>; // expected-error {{ diff erent template parameters}} using ok2 = Tt0<t0>; - using err4 = Tt0<it>; // expected-error@#Tt0 {{template argument for non-type template parameter must be an expression}} - // expected-note@-1 {{ diff erent template parameters}} + using err4 = Tt0<it>; // expected-error {{ diff erent template parameters}} } namespace Auto { - template<template<int> typename T> struct TInt {}; // #TInt - template<template<int*> typename T> struct TIntPtr {}; // #TIntPtr + template<template<int> typename T> struct TInt {}; + template<template<int*> typename T> struct TIntPtr {}; template<template<auto> typename T> struct TAuto {}; template<template<auto*> typename T> struct TAutoPtr {}; template<template<decltype(auto)> typename T> struct TDecltypeAuto {}; template<auto> struct Auto; - template<auto*> struct AutoPtr; // #AutoPtr + template<auto*> struct AutoPtr; template<decltype(auto)> struct DecltypeAuto; template<int> struct Int; template<int*> struct IntPtr; TInt<Auto> ia; - TInt<AutoPtr> iap; // expected-error@#TInt {{non-type template parameter '' with type 'auto *' has incompatible initializer of type 'int'}} - // expected-note@-1 {{ diff erent template parameters}} + TInt<AutoPtr> iap; // FIXME: ill-formed (?) TInt<DecltypeAuto> ida; TInt<Int> ii; - TInt<IntPtr> iip; // expected-error@#TInt {{conversion from 'int' to 'int *' is not allowed in a converted constant expression}} - // expected-note@-1 {{ diff erent template parameters}} + TInt<IntPtr> iip; // expected-error {{ diff erent template parameters}} TIntPtr<Auto> ipa; TIntPtr<AutoPtr> ipap; TIntPtr<DecltypeAuto> ipda; - TIntPtr<Int> ipi; // expected-error@#TIntPtr {{value of type 'int *' is not implicitly convertible to 'int'}} - // expected-note@-1 {{ diff erent template parameters}} + TIntPtr<Int> ipi; // expected-error {{ diff erent template parameters}} TIntPtr<IntPtr> ipip; TAuto<Auto> aa; - TAuto<AutoPtr> aap; // expected-error@#AutoPtr {{could not match 'auto *' against 'auto'}} - // expected-note@-1 {{ diff erent template parameters}} + TAuto<AutoPtr> aap; // FIXME: ill-formed (?) TAuto<Int> ai; // FIXME: ill-formed (?) TAuto<IntPtr> aip; // FIXME: ill-formed (?) @@ -128,8 +111,7 @@ namespace Auto { // parameters (such as 'user-defined-type &') that are not valid 'auto' // parameters. TDecltypeAuto<Auto> daa; - TDecltypeAuto<AutoPtr> daap; // expected-error@#AutoPtr {{could not match 'auto *' against 'decltype(auto)'}} - // expected-note@-1 {{ diff erent template parameters}} + TDecltypeAuto<AutoPtr> daap; // FIXME: should probably be ill-formed int n; template<auto A, decltype(A) B = &n> struct SubstFailure; @@ -146,7 +128,7 @@ namespace GH62529 { } // namespace GH62529 namespace GH101394 { - struct X {}; // #X + struct X {}; struct Y { constexpr Y(const X &) {} }; @@ -157,12 +139,8 @@ namespace GH101394 { template struct A<B>; } // namespace t1 namespace t2 { - template<template<Y> class> struct A {}; // #A - template<X> struct B; // #B - template struct A<B>; - // expected-error@#A {{no viable conversion from 'const Y' to 'X'}} - // expected-note@-2 {{ diff erent template parameters}} - // expected-note@#X 2{{not viable}} - // expected-note@#B {{passing argument to parameter here}} + template<template<Y> class> struct A {}; + template<X> struct B; + template struct A<B>; // expected-error {{ diff erent template parameters}} } // namespace t2 } // namespace GH101394 diff --git a/clang/test/Templight/templight-empty-entries-fix.cpp b/clang/test/Templight/templight-empty-entries-fix.cpp index d13b748068efec..e17be9012e59cc 100644 --- a/clang/test/Templight/templight-empty-entries-fix.cpp +++ b/clang/test/Templight/templight-empty-entries-fix.cpp @@ -314,18 +314,6 @@ void foo() { // CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:289:35'$}} // CHECK: {{^poi:[ ]+''$}} // CHECK-LABEL: {{^---$}} -// CHECK: {{^name:[ ]+unnamed template template parameter 0 of d$}} -// CHECK: {{^kind:[ ]+PartialOrderingTTP$}} -// CHECK: {{^event:[ ]+Begin$}} -// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:289:35'$}} -// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:295:5'$}} -// CHECK-LABEL: {{^---$}} -// CHECK: {{^name:[ ]+unnamed template template parameter 0 of d$}} -// CHECK: {{^kind:[ ]+PartialOrderingTTP$}} -// CHECK: {{^event:[ ]+End$}} -// CHECK: {{^orig:[ ]+'.*templight-empty-entries-fix.cpp:289:35'$}} -// CHECK: {{^poi:[ ]+'.*templight-empty-entries-fix.cpp:295:5'$}} -// CHECK-LABEL: {{^---$}} // CHECK: {{^name:[ ]+d$}} // CHECK: {{^kind:[ ]+ExplicitTemplateArgumentSubstitution$}} // CHECK: {{^event:[ ]+End$}} diff --git a/clang/test/Templight/templight-prior-template-arg.cpp b/clang/test/Templight/templight-prior-template-arg.cpp index 14bcb6a4d48f6b..e9b1dd47bb603a 100644 --- a/clang/test/Templight/templight-prior-template-arg.cpp +++ b/clang/test/Templight/templight-prior-template-arg.cpp @@ -10,76 +10,63 @@ class B {}; // CHECK: {{^kind:[ ]+PriorTemplateArgumentSubstitution$}} // CHECK: {{^event:[ ]+Begin$}} // CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:5:40'}} -// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:1'$}} +// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:1'$}} // CHECK-LABEL: {{^---$}} // CHECK: {{^name:[ ]+'B::Outer'$}} // CHECK: {{^kind:[ ]+PriorTemplateArgumentSubstitution$}} // CHECK: {{^event:[ ]+End$}} // CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:5:40'}} -// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:1'$}} -// -// CHECK-LABEL: {{^---$}} -// CHECK: {{^name:[ ]+'B::Outer'$}} -// CHECK: {{^kind:[ ]+PartialOrderingTTP$}} -// CHECK: {{^event:[ ]+Begin$}} -// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:5:40'}} -// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:3'$}} -// CHECK-LABEL: {{^---$}} -// CHECK: {{^name:[ ]+'B::Outer'$}} -// CHECK: {{^kind:[ ]+PartialOrderingTTP$}} -// CHECK: {{^event:[ ]+End$}} -// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:5:40'}} -// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:3'$}} +// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:1'$}} // // CHECK-LABEL: {{^---$}} // CHECK: {{^name:[ ]+'B<A>'$}} // CHECK: {{^kind:[ ]+TemplateInstantiation$}} // CHECK: {{^event:[ ]+Begin$}} // CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}} -// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:6'$}} +// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}} // CHECK-LABEL: {{^---$}} // CHECK: {{^name:[ ]+'B<A>'$}} // CHECK: {{^kind:[ ]+TemplateInstantiation$}} // CHECK: {{^event:[ ]+End$}} // CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}} -// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:6'$}} +// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}} // // CHECK-LABEL: {{^---$}} // CHECK: {{^name:[ ]+'B<A>'$}} // CHECK: {{^kind:[ ]+TemplateInstantiation$}} // CHECK: {{^event:[ ]+Begin$}} // CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}} -// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:6'$}} +// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}} // CHECK-LABEL: {{^---$}} // CHECK: {{^name:[ ]+'B<A>'$}} // CHECK: {{^kind:[ ]+TemplateInstantiation$}} // CHECK: {{^event:[ ]+End$}} // CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}} -// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:6'$}} +// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}} // // CHECK-LABEL: {{^---$}} // CHECK: {{^name:[ ]+'B<A>'$}} // CHECK: {{^kind:[ ]+Memoization$}} // CHECK: {{^event:[ ]+Begin$}} // CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}} -// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:6'$}} +// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}} // CHECK-LABEL: {{^---$}} // CHECK: {{^name:[ ]+'B<A>'$}} // CHECK: {{^kind:[ ]+Memoization$}} // CHECK: {{^event:[ ]+End$}} // CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}} -// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:6'$}} +// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}} // // CHECK-LABEL: {{^---$}} // CHECK: {{^name:[ ]+'B<A>'$}} // CHECK: {{^kind:[ ]+Memoization$}} // CHECK: {{^event:[ ]+Begin$}} // CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}} -// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:6'$}} +// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}} // CHECK-LABEL: {{^---$}} // CHECK: {{^name:[ ]+'B<A>'$}} // CHECK: {{^kind:[ ]+Memoization$}} // CHECK: {{^event:[ ]+End$}} // CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}} -// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:85:6'$}} +// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}} B<A> b; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits