@@ -5862,10 +5862,42 @@ static bool isAtLeastAsSpecializedAs(
5862
5862
return true ;
5863
5863
}
5864
5864
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
+
5865
5896
FunctionTemplateDecl *Sema::getMoreSpecializedTemplate (
5866
5897
FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc,
5867
5898
TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1,
5868
- QualType RawObj1Ty, QualType RawObj2Ty, bool Reversed) {
5899
+ QualType RawObj1Ty, QualType RawObj2Ty, bool Reversed,
5900
+ bool PartialOverloading) {
5869
5901
SmallVector<QualType> Args1;
5870
5902
SmallVector<QualType> Args2;
5871
5903
const FunctionDecl *FD1 = FT1->getTemplatedDecl ();
@@ -6001,34 +6033,27 @@ FunctionTemplateDecl *Sema::getMoreSpecializedTemplate(
6001
6033
return FT1;
6002
6034
}
6003
6035
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) {
6007
6041
QualType T1 = Param1[i].getCanonicalType ();
6008
6042
QualType T2 = Param2[i].getCanonicalType ();
6009
6043
auto *TST1 = dyn_cast<TemplateSpecializationType>(T1);
6010
6044
auto *TST2 = dyn_cast<TemplateSpecializationType>(T2);
6011
6045
if (!TST1 || !TST2)
6012
6046
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 ;
6031
6054
}
6055
+ llvm_unreachable (
6056
+ " unknown MoreSpecializedTrailingPackTieBreakerResult value" );
6032
6057
}
6033
6058
6034
6059
if (!Context.getLangOpts ().CPlusPlus20 )
@@ -6375,28 +6400,15 @@ getMoreSpecialized(Sema &S, QualType T1, QualType T2, TemplateLikeDecl *P1,
6375
6400
if (!Better1 && !Better2)
6376
6401
return nullptr ;
6377
6402
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 ;
6400
6412
}
6401
6413
6402
6414
if (!S.Context .getLangOpts ().CPlusPlus20 )
0 commit comments