Author: Mikhail Goncharov Date: 2024-10-11T14:47:21+02:00 New Revision: bdd46cc6b74eeed14936f1373bbb6446e09979fe
URL: https://github.com/llvm/llvm-project/commit/bdd46cc6b74eeed14936f1373bbb6446e09979fe DIFF: https://github.com/llvm/llvm-project/commit/bdd46cc6b74eeed14936f1373bbb6446e09979fe.diff LOG: Revert "[clang] CWG2398: improve overload resolution backwards compat (#107350)" See discussion in https://github.com/llvm/llvm-project/pull/111711 This reverts commit 224519b08945637a85e9798c78286643288f7b77. Added: Modified: clang/docs/ReleaseNotes.rst clang/include/clang/Sema/Sema.h clang/include/clang/Sema/TemplateDeduction.h clang/lib/Sema/SemaLookup.cpp clang/lib/Sema/SemaTemplate.cpp clang/lib/Sema/SemaTemplateDeduction.cpp clang/lib/Sema/SemaTemplateInstantiate.cpp clang/test/SemaTemplate/cwg2398.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index df165b91252505..00376ce2a6008b 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -207,8 +207,7 @@ Resolutions to C++ Defect Reports (`CWG2351: void{} <https://cplusplus.github.io/CWG/issues/2351.html>`_). - Clang now has improved resolution to CWG2398, allowing class templates to have - default arguments deduced when partial ordering, and better backwards compatibility - in overload resolution. + default arguments deduced when partial ordering. - Clang now allows comparing unequal object pointers that have been cast to ``void *`` in constant expressions. These comparisons always worked in non-constant expressions. diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 66b0846f286a81..49c593bf88c989 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -11638,8 +11638,7 @@ class Sema final : public SemaBase { SourceLocation RAngleLoc, unsigned ArgumentPackIndex, SmallVectorImpl<TemplateArgument> &SugaredConverted, SmallVectorImpl<TemplateArgument> &CanonicalConverted, - CheckTemplateArgumentKind CTAK, - bool *MatchedPackOnParmToNonPackOnArg); + CheckTemplateArgumentKind CTAK); /// Check that the given template arguments can be provided to /// the given template, converting the arguments along the way. @@ -11686,8 +11685,7 @@ class Sema final : public SemaBase { SmallVectorImpl<TemplateArgument> &SugaredConverted, SmallVectorImpl<TemplateArgument> &CanonicalConverted, bool UpdateArgsWithConversions = true, - bool *ConstraintsNotSatisfied = nullptr, bool PartialOrderingTTP = false, - bool *MatchedPackOnParmToNonPackOnArg = nullptr); + bool *ConstraintsNotSatisfied = nullptr, bool PartialOrderingTTP = false); bool CheckTemplateTypeArgument( TemplateTypeParmDecl *Param, TemplateArgumentLoc &Arg, @@ -11721,8 +11719,7 @@ class Sema final : public SemaBase { /// It returns true if an error occurred, and false otherwise. bool CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param, TemplateParameterList *Params, - TemplateArgumentLoc &Arg, bool IsDeduced, - bool *MatchedPackOnParmToNonPackOnArg); + TemplateArgumentLoc &Arg, bool IsDeduced); void NoteTemplateLocation(const NamedDecl &Decl, std::optional<SourceRange> ParamRange = {}); @@ -12423,7 +12420,7 @@ class Sema final : public SemaBase { bool isTemplateTemplateParameterAtLeastAsSpecializedAs( TemplateParameterList *PParam, TemplateDecl *PArg, TemplateDecl *AArg, const DefaultArguments &DefaultArgs, SourceLocation ArgLoc, - bool IsDeduced, bool *MatchedPackOnParmToNonPackOnArg); + bool IsDeduced); /// Mark which template parameters are used in a given expression. /// @@ -13422,8 +13419,7 @@ class Sema final : public SemaBase { bool InstantiateClassTemplateSpecialization( SourceLocation PointOfInstantiation, ClassTemplateSpecializationDecl *ClassTemplateSpec, - TemplateSpecializationKind TSK, bool Complain = true, - bool PrimaryHasMatchedPackOnParmToNonPackOnArg = false); + TemplateSpecializationKind TSK, bool Complain = true); /// Instantiates the definitions of all of the member /// of the given class, which is an instantiation of a class template diff --git a/clang/include/clang/Sema/TemplateDeduction.h b/clang/include/clang/Sema/TemplateDeduction.h index 9c12eef5c42a06..28b014fd84e4b3 100644 --- a/clang/include/clang/Sema/TemplateDeduction.h +++ b/clang/include/clang/Sema/TemplateDeduction.h @@ -51,11 +51,6 @@ class TemplateDeductionInfo { /// Have we suppressed an error during deduction? bool HasSFINAEDiagnostic = false; - /// Have we matched any packs on the parameter side, versus any non-packs on - /// the argument side, in a context where the opposite matching is also - /// allowed? - bool MatchedPackOnParmToNonPackOnArg = false; - /// The template parameter depth for which we're performing deduction. unsigned DeducedDepth; @@ -92,14 +87,6 @@ class TemplateDeductionInfo { return DeducedDepth; } - bool hasMatchedPackOnParmToNonPackOnArg() const { - return MatchedPackOnParmToNonPackOnArg; - } - - void setMatchedPackOnParmToNonPackOnArg() { - MatchedPackOnParmToNonPackOnArg = true; - } - /// Get the number of explicitly-specified arguments. unsigned getNumExplicitArgs() const { return ExplicitArgs; diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 31422c213ac249..f3f62474d06441 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -3666,8 +3666,7 @@ Sema::LookupLiteralOperator(Scope *S, LookupResult &R, TemplateArgumentLoc Arg(TemplateArgument(StringLit), StringLit); if (CheckTemplateArgument( Params->getParam(0), Arg, FD, R.getNameLoc(), R.getNameLoc(), - 0, SugaredChecked, CanonicalChecked, CTAK_Specified, - /*MatchedPackOnParmToNonPackOnArg=*/nullptr) || + 0, SugaredChecked, CanonicalChecked, CTAK_Specified) || Trap.hasErrorOccurred()) IsTemplate = false; } diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 4f13669c2490c0..226c1172a059d4 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -5179,7 +5179,7 @@ bool Sema::CheckTemplateArgument( unsigned ArgumentPackIndex, SmallVectorImpl<TemplateArgument> &SugaredConverted, SmallVectorImpl<TemplateArgument> &CanonicalConverted, - CheckTemplateArgumentKind CTAK, bool *MatchedPackOnParmToNonPackOnArg) { + CheckTemplateArgumentKind CTAK) { // Check template type parameters. if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) return CheckTemplateTypeArgument(TTP, Arg, SugaredConverted, @@ -5395,8 +5395,7 @@ bool Sema::CheckTemplateArgument( case TemplateArgument::Template: case TemplateArgument::TemplateExpansion: if (CheckTemplateTemplateArgument(TempParm, Params, Arg, - /*IsDeduced=*/CTAK != CTAK_Specified, - MatchedPackOnParmToNonPackOnArg)) + /*IsDeduced=*/CTAK != CTAK_Specified)) return true; SugaredConverted.push_back(Arg.getArgument()); @@ -5470,7 +5469,7 @@ bool Sema::CheckTemplateArgumentList( SmallVectorImpl<TemplateArgument> &SugaredConverted, SmallVectorImpl<TemplateArgument> &CanonicalConverted, bool UpdateArgsWithConversions, bool *ConstraintsNotSatisfied, - bool PartialOrderingTTP, bool *MatchedPackOnParmToNonPackOnArg) { + bool PartialOrderingTTP) { if (ConstraintsNotSatisfied) *ConstraintsNotSatisfied = false; @@ -5546,10 +5545,10 @@ bool Sema::CheckTemplateArgumentList( if (ArgIdx < NumArgs) { // Check the template argument we were given. - if (CheckTemplateArgument( - *Param, NewArgs[ArgIdx], Template, TemplateLoc, RAngleLoc, - SugaredArgumentPack.size(), SugaredConverted, CanonicalConverted, - CTAK_Specified, MatchedPackOnParmToNonPackOnArg)) + if (CheckTemplateArgument(*Param, NewArgs[ArgIdx], Template, TemplateLoc, + RAngleLoc, SugaredArgumentPack.size(), + SugaredConverted, CanonicalConverted, + CTAK_Specified)) return true; CanonicalConverted.back().setIsDefaulted( @@ -5707,8 +5706,7 @@ bool Sema::CheckTemplateArgumentList( // Check the default template argument. if (CheckTemplateArgument(*Param, Arg, Template, TemplateLoc, RAngleLoc, 0, SugaredConverted, CanonicalConverted, - CTAK_Specified, - /*MatchedPackOnParmToNonPackOnArg=*/nullptr)) + CTAK_Specified)) return true; SugaredConverted.back().setIsDefaulted(true); @@ -7291,10 +7289,10 @@ static void DiagnoseTemplateParameterListArityMismatch( Sema &S, TemplateParameterList *New, TemplateParameterList *Old, Sema::TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc); -bool Sema::CheckTemplateTemplateArgument( - TemplateTemplateParmDecl *Param, TemplateParameterList *Params, - TemplateArgumentLoc &Arg, bool IsDeduced, - bool *MatchedPackOnParmToNonPackOnArg) { +bool Sema::CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param, + TemplateParameterList *Params, + TemplateArgumentLoc &Arg, + bool IsDeduced) { TemplateName Name = Arg.getArgument().getAsTemplateOrTemplatePattern(); auto [Template, DefaultArgs] = Name.getTemplateDeclAndDefaultArgs(); if (!Template) { @@ -7338,8 +7336,7 @@ bool Sema::CheckTemplateTemplateArgument( // 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, - MatchedPackOnParmToNonPackOnArg)) + Params, Param, Template, DefaultArgs, Arg.getLocation(), IsDeduced)) return true; // P2113 // C++20[temp.func.order]p2 @@ -9757,14 +9754,11 @@ DeclResult Sema::ActOnExplicitInstantiation( // Check that the template argument list is well-formed for this // template. - bool PrimaryHasMatchedPackOnParmToNonPackOnArg = false; SmallVector<TemplateArgument, 4> SugaredConverted, CanonicalConverted; - if (CheckTemplateArgumentList( - ClassTemplate, TemplateNameLoc, TemplateArgs, - /*DefaultArgs=*/{}, false, SugaredConverted, CanonicalConverted, - /*UpdateArgsWithConversions=*/true, - /*ConstraintsNotSatisfied=*/nullptr, /*PartialOrderingTTP=*/false, - &PrimaryHasMatchedPackOnParmToNonPackOnArg)) + if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, TemplateArgs, + /*DefaultArgs=*/{}, false, SugaredConverted, + CanonicalConverted, + /*UpdateArgsWithConversions=*/true)) return true; // Find the class template specialization declaration that @@ -9885,9 +9879,7 @@ DeclResult Sema::ActOnExplicitInstantiation( = cast_or_null<ClassTemplateSpecializationDecl>( Specialization->getDefinition()); if (!Def) - InstantiateClassTemplateSpecialization( - TemplateNameLoc, Specialization, TSK, - /*Complain=*/true, PrimaryHasMatchedPackOnParmToNonPackOnArg); + InstantiateClassTemplateSpecialization(TemplateNameLoc, Specialization, TSK); else if (TSK == TSK_ExplicitInstantiationDefinition) { MarkVTableUsed(TemplateNameLoc, Specialization, true); Specialization->setPointOfInstantiation(Def->getPointOfInstantiation()); diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 48a39a90f72a8b..03ff8145e3b4ac 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -2767,12 +2767,8 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, for (; hasTemplateArgumentForDeduction(As, ArgIdx) && PackScope.hasNextElement(); ++ArgIdx) { - if (!As[ArgIdx].isPackExpansion()) { - if (!FoldPackParameter) - return TemplateDeductionResult::MiscellaneousDeductionFailure; - if (FoldPackArgument) - Info.setMatchedPackOnParmToNonPackOnArg(); - } + if (!FoldPackParameter && !As[ArgIdx].isPackExpansion()) + return TemplateDeductionResult::MiscellaneousDeductionFailure; // Deduce template arguments from the pattern. if (auto Result = DeduceTemplateArguments( S, TemplateParams, Pattern, As[ArgIdx], Info, PartialOrdering, @@ -2966,20 +2962,15 @@ static bool ConvertDeducedTemplateArgument( TemplateArgumentLoc ArgLoc = S.getTrivialTemplateArgumentLoc( Arg, QualType(), Info.getLocation(), Param); - bool MatchedPackOnParmToNonPackOnArg = false; // Check the template argument, converting it as necessary. - auto Res = S.CheckTemplateArgument( + return S.CheckTemplateArgument( Param, ArgLoc, Template, Template->getLocation(), Template->getSourceRange().getEnd(), ArgumentPackIndex, SugaredOutput, CanonicalOutput, IsDeduced ? (Arg.wasDeducedFromArrayBound() ? Sema::CTAK_DeducedFromArrayBound : Sema::CTAK_Deduced) - : Sema::CTAK_Specified, - &MatchedPackOnParmToNonPackOnArg); - if (MatchedPackOnParmToNonPackOnArg) - Info.setMatchedPackOnParmToNonPackOnArg(); - return Res; + : Sema::CTAK_Specified); }; if (Arg.getKind() == TemplateArgument::Pack) { @@ -3174,8 +3165,7 @@ static TemplateDeductionResult ConvertDeducedTemplateArguments( // Check whether we can actually use the default argument. if (S.CheckTemplateArgument( Param, DefArg, TD, TD->getLocation(), TD->getSourceRange().getEnd(), - 0, SugaredBuilder, CanonicalBuilder, Sema::CTAK_Specified, - /*MatchedPackOnParmToNonPackOnArg=*/nullptr)) { + 0, SugaredBuilder, CanonicalBuilder, Sema::CTAK_Specified)) { Info.Param = makeTemplateParameter( const_cast<NamedDecl *>(TemplateParams->getParam(I))); // FIXME: These template arguments are temporary. Free them! @@ -3324,20 +3314,16 @@ FinishTemplateArgumentDeduction( return TemplateDeductionResult::SubstitutionFailure; } - bool MatchedPackOnParmToNonPackOnArg = false; bool ConstraintsNotSatisfied; SmallVector<TemplateArgument, 4> SugaredConvertedInstArgs, CanonicalConvertedInstArgs; if (S.CheckTemplateArgumentList( Template, Partial->getLocation(), InstArgs, /*DefaultArgs=*/{}, false, SugaredConvertedInstArgs, CanonicalConvertedInstArgs, - /*UpdateArgsWithConversions=*/true, &ConstraintsNotSatisfied, - /*PartialOrderingTTP=*/false, &MatchedPackOnParmToNonPackOnArg)) + /*UpdateArgsWithConversions=*/true, &ConstraintsNotSatisfied)) return ConstraintsNotSatisfied ? TemplateDeductionResult::ConstraintsNotSatisfied : TemplateDeductionResult::SubstitutionFailure; - if (MatchedPackOnParmToNonPackOnArg) - Info.setMatchedPackOnParmToNonPackOnArg(); TemplateParameterList *TemplateParams = Template->getTemplateParameters(); for (unsigned I = 0, E = TemplateParams->size(); I != E; ++I) { @@ -6479,8 +6465,8 @@ bool Sema::isMoreSpecializedThanPrimary( bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs( TemplateParameterList *P, TemplateDecl *PArg, TemplateDecl *AArg, - const DefaultArguments &DefaultArgs, SourceLocation ArgLoc, bool IsDeduced, - bool *MatchedPackOnParmToNonPackOnArg) { + const DefaultArguments &DefaultArgs, SourceLocation ArgLoc, + 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 @@ -6532,11 +6518,11 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs( // 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, - /*UpdateArgsWithConversions=*/true, - /*ConstraintsNotSatisfied=*/nullptr, - /*PartialOrderingTTP=*/true, MatchedPackOnParmToNonPackOnArg)) + if (CheckTemplateArgumentList(AArg, ArgLoc, PArgList, DefaultArgs, false, + PArgs, CanonicalPArgs, + /*UpdateArgsWithConversions=*/true, + /*ConstraintsNotSatisfied=*/nullptr, + /*PartialOrderingTTP=*/true)) return false; } @@ -6562,9 +6548,6 @@ bool Sema::isTemplateTemplateParameterAtLeastAsSpecializedAs( IsDeduced ? PackFold::ArgumentToParameter : PackFold::Both, /*HasDeducedAnyParam=*/nullptr)) { case clang::TemplateDeductionResult::Success: - if (MatchedPackOnParmToNonPackOnArg && - Info.hasMatchedPackOnParmToNonPackOnArg()) - *MatchedPackOnParmToNonPackOnArg = true; break; case TemplateDeductionResult::MiscellaneousDeductionFailure: diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 2f60c0beb22e73..de71774bd8e559 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -4017,11 +4017,11 @@ bool Sema::usesPartialOrExplicitSpecialization( /// Get the instantiation pattern to use to instantiate the definition of a /// given ClassTemplateSpecializationDecl (either the pattern of the primary /// template or of a partial specialization). -static ActionResult<CXXRecordDecl *> getPatternForClassTemplateSpecialization( +static ActionResult<CXXRecordDecl *> +getPatternForClassTemplateSpecialization( Sema &S, SourceLocation PointOfInstantiation, ClassTemplateSpecializationDecl *ClassTemplateSpec, - TemplateSpecializationKind TSK, - bool PrimaryHasMatchedPackOnParmToNonPackOnArg) { + TemplateSpecializationKind TSK) { Sema::InstantiatingTemplate Inst(S, PointOfInstantiation, ClassTemplateSpec); if (Inst.isInvalid()) return {/*Invalid=*/true}; @@ -4044,7 +4044,7 @@ static ActionResult<CXXRecordDecl *> getPatternForClassTemplateSpecialization( // specialization with the template argument lists of the partial // specializations. typedef PartialSpecMatchResult MatchResult; - SmallVector<MatchResult, 4> Matched, ExtraMatched; + SmallVector<MatchResult, 4> Matched; SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs; Template->getPartialSpecializations(PartialSpecs); TemplateSpecCandidateSet FailedCandidates(PointOfInstantiation); @@ -4061,13 +4061,11 @@ static ActionResult<CXXRecordDecl *> getPatternForClassTemplateSpecialization( MakeDeductionFailureInfo(S.Context, Result, Info)); (void)Result; } else { - auto &List = - Info.hasMatchedPackOnParmToNonPackOnArg() ? ExtraMatched : Matched; - List.push_back(MatchResult{Partial, Info.takeCanonical()}); + Matched.push_back(PartialSpecMatchResult()); + Matched.back().Partial = Partial; + Matched.back().Args = Info.takeCanonical(); } } - if (Matched.empty() && PrimaryHasMatchedPackOnParmToNonPackOnArg) - Matched = std::move(ExtraMatched); // If we're dealing with a member template where the template parameters // have been instantiated, this provides the original template parameters @@ -4170,8 +4168,7 @@ static ActionResult<CXXRecordDecl *> getPatternForClassTemplateSpecialization( bool Sema::InstantiateClassTemplateSpecialization( SourceLocation PointOfInstantiation, ClassTemplateSpecializationDecl *ClassTemplateSpec, - TemplateSpecializationKind TSK, bool Complain, - bool PrimaryHasMatchedPackOnParmToNonPackOnArg) { + TemplateSpecializationKind TSK, bool Complain) { // Perform the actual instantiation on the canonical declaration. ClassTemplateSpec = cast<ClassTemplateSpecializationDecl>( ClassTemplateSpec->getCanonicalDecl()); @@ -4179,9 +4176,8 @@ bool Sema::InstantiateClassTemplateSpecialization( return true; ActionResult<CXXRecordDecl *> Pattern = - getPatternForClassTemplateSpecialization( - *this, PointOfInstantiation, ClassTemplateSpec, TSK, - PrimaryHasMatchedPackOnParmToNonPackOnArg); + getPatternForClassTemplateSpecialization(*this, PointOfInstantiation, + ClassTemplateSpec, TSK); if (!Pattern.isUsable()) return Pattern.isInvalid(); diff --git a/clang/test/SemaTemplate/cwg2398.cpp b/clang/test/SemaTemplate/cwg2398.cpp index 56091e84cf4e95..b9e9e9f0c97f26 100644 --- a/clang/test/SemaTemplate/cwg2398.cpp +++ b/clang/test/SemaTemplate/cwg2398.cpp @@ -156,14 +156,16 @@ namespace ttp_defaults { namespace ttp_only { template <template <class... > class TT1> struct A { static constexpr int V = 0; }; template <template <class > class TT2> struct A<TT2> { static constexpr int V = 1; }; + // new-note@-1 {{partial specialization matches}} template <template <class, class> class TT3> struct A<TT3> { static constexpr int V = 2; }; + // new-note@-1 {{partial specialization matches}} template <class ... > struct B; template <class > struct C; template <class, class > struct D; template <class, class, class> struct E; - static_assert(A<B>::V == 0); + static_assert(A<B>::V == 0); // new-error {{ambiguous partial specializations}} static_assert(A<C>::V == 1); static_assert(A<D>::V == 2); static_assert(A<E>::V == 0); @@ -410,9 +412,11 @@ namespace partial { 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; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits