@@ -5862,10 +5862,42 @@ static bool isAtLeastAsSpecializedAs(
58625862 return true ;
58635863}
58645864
5865+ enum class MoreSpecializedTrailingPackTieBreakerResult { Equal, Less, More };
5866+
5867+ // This a speculative fix for CWG1432 (Similar to the fix for CWG1395) that
5868+ // there is no wording or even resolution for this issue.
5869+ static MoreSpecializedTrailingPackTieBreakerResult
5870+ getMoreSpecializedTrailingPackTieBreaker (
5871+ const TemplateSpecializationType *TST1,
5872+ const TemplateSpecializationType *TST2) {
5873+ ArrayRef<TemplateArgument> As1 = TST1->template_arguments (),
5874+ As2 = TST2->template_arguments ();
5875+ const TemplateArgument &TA1 = As1.back (), &TA2 = As2.back ();
5876+ bool IsPack = TA1.getKind () == TemplateArgument::Pack;
5877+ assert (IsPack == (TA2.getKind () == TemplateArgument::Pack));
5878+ if (!IsPack)
5879+ return MoreSpecializedTrailingPackTieBreakerResult::Equal;
5880+ assert (As1.size () == As2.size ());
5881+
5882+ unsigned PackSize1 = TA1.pack_size (), PackSize2 = TA2.pack_size ();
5883+ bool IsPackExpansion1 =
5884+ PackSize1 && TA1.pack_elements ().back ().isPackExpansion ();
5885+ bool IsPackExpansion2 =
5886+ PackSize2 && TA2.pack_elements ().back ().isPackExpansion ();
5887+ if (PackSize1 == PackSize2 && IsPackExpansion1 == IsPackExpansion2)
5888+ return MoreSpecializedTrailingPackTieBreakerResult::Equal;
5889+ if (PackSize1 > PackSize2 && IsPackExpansion1)
5890+ return MoreSpecializedTrailingPackTieBreakerResult::More;
5891+ if (PackSize1 < PackSize2 && IsPackExpansion2)
5892+ return MoreSpecializedTrailingPackTieBreakerResult::Less;
5893+ return MoreSpecializedTrailingPackTieBreakerResult::Equal;
5894+ }
5895+
58655896FunctionTemplateDecl *Sema::getMoreSpecializedTemplate (
58665897 FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
58675898 TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
5868- QualType RawObj1Ty, QualType RawObj2Ty, bool Reversed) {
5899+ QualType RawObj1Ty, QualType RawObj2Ty, bool Reversed,
5900+ bool PartialOverloading) {
58695901 SmallVector<QualType> Args1;
58705902 SmallVector<QualType> Args2;
58715903 const FunctionDecl *FD1 = FT1->getTemplatedDecl ();
@@ -6001,34 +6033,27 @@ FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
60016033 return FT1;
60026034 }
60036035
6004- // This a speculative fix for CWG1432 (Similar to the fix for CWG1395) that
6005- // there is no wording or even resolution for this issue.
6006- for (int i = 0 , e = std::min (NumParams1, NumParams2); i < e; ++i) {
6036+ // Skip this tie breaker if we are performing overload resolution with partial
6037+ // arguments, as this breaks some assumptions about how closely related the
6038+ // candidates are.
6039+ for (int i = 0 , e = std::min (NumParams1, NumParams2);
6040+ !PartialOverloading && i < e; ++i) {
60076041 QualType T1 = Param1[i].getCanonicalType ();
60086042 QualType T2 = Param2[i].getCanonicalType ();
60096043 auto *TST1 = dyn_cast<TemplateSpecializationType>(T1);
60106044 auto *TST2 = dyn_cast<TemplateSpecializationType>(T2);
60116045 if (!TST1 || !TST2)
60126046 continue ;
6013- const TemplateArgument &TA1 = TST1->template_arguments ().back ();
6014- if (TA1.getKind () == TemplateArgument::Pack) {
6015- assert (TST1->template_arguments ().size () ==
6016- TST2->template_arguments ().size ());
6017- const TemplateArgument &TA2 = TST2->template_arguments ().back ();
6018- assert (TA2.getKind () == TemplateArgument::Pack);
6019- unsigned PackSize1 = TA1.pack_size ();
6020- unsigned PackSize2 = TA2.pack_size ();
6021- bool IsPackExpansion1 =
6022- PackSize1 && TA1.pack_elements ().back ().isPackExpansion ();
6023- bool IsPackExpansion2 =
6024- PackSize2 && TA2.pack_elements ().back ().isPackExpansion ();
6025- if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
6026- if (PackSize1 > PackSize2 && IsPackExpansion1)
6027- return FT2;
6028- if (PackSize1 < PackSize2 && IsPackExpansion2)
6029- return FT1;
6030- }
6047+ switch (getMoreSpecializedTrailingPackTieBreaker (TST1, TST2)) {
6048+ case MoreSpecializedTrailingPackTieBreakerResult::Less:
6049+ return FT1;
6050+ case MoreSpecializedTrailingPackTieBreakerResult::More:
6051+ return FT2;
6052+ case MoreSpecializedTrailingPackTieBreakerResult::Equal:
6053+ continue ;
60316054 }
6055+ llvm_unreachable (
6056+ " unknown MoreSpecializedTrailingPackTieBreakerResult value" );
60326057 }
60336058
60346059 if (!Context.getLangOpts ().CPlusPlus20 )
@@ -6375,28 +6400,15 @@ getMoreSpecialized(Sema &S, QualType T1, QualType T2, TemplateLikeDecl *P1,
63756400 if (!Better1 && !Better2)
63766401 return nullptr ;
63776402
6378- // This a speculative fix for CWG1432 (Similar to the fix for CWG1395) that
6379- // there is no wording or even resolution for this issue.
6380- auto *TST1 = cast<TemplateSpecializationType>(T1);
6381- auto *TST2 = cast<TemplateSpecializationType>(T2);
6382- const TemplateArgument &TA1 = TST1->template_arguments ().back ();
6383- if (TA1.getKind () == TemplateArgument::Pack) {
6384- assert (TST1->template_arguments ().size () ==
6385- TST2->template_arguments ().size ());
6386- const TemplateArgument &TA2 = TST2->template_arguments ().back ();
6387- assert (TA2.getKind () == TemplateArgument::Pack);
6388- unsigned PackSize1 = TA1.pack_size ();
6389- unsigned PackSize2 = TA2.pack_size ();
6390- bool IsPackExpansion1 =
6391- PackSize1 && TA1.pack_elements ().back ().isPackExpansion ();
6392- bool IsPackExpansion2 =
6393- PackSize2 && TA2.pack_elements ().back ().isPackExpansion ();
6394- if (PackSize1 != PackSize2 && IsPackExpansion1 != IsPackExpansion2) {
6395- if (PackSize1 > PackSize2 && IsPackExpansion1)
6396- return GetP2 ()(P1, P2);
6397- if (PackSize1 < PackSize2 && IsPackExpansion2)
6398- return P1;
6399- }
6403+ switch (getMoreSpecializedTrailingPackTieBreaker (
6404+ cast<TemplateSpecializationType>(T1),
6405+ cast<TemplateSpecializationType>(T2))) {
6406+ case MoreSpecializedTrailingPackTieBreakerResult::Less:
6407+ return P1;
6408+ case MoreSpecializedTrailingPackTieBreakerResult::More:
6409+ return GetP2 ()(P1, P2);
6410+ case MoreSpecializedTrailingPackTieBreakerResult::Equal:
6411+ break ;
64006412 }
64016413
64026414 if (!S.Context .getLangOpts ().CPlusPlus20 )
0 commit comments