Skip to content

Commit f495872

Browse files
authored
[clang] fix P3310 overload resolution flag propagation (#125372)
1 parent f4c2e5d commit f495872

15 files changed

+6141
-44
lines changed

clang/include/clang/AST/DeclTemplate.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1841,15 +1841,23 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
18411841
LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
18421842
unsigned SpecializationKind : 3;
18431843

1844+
/// Indicate that we have matched a parameter pack with a non pack
1845+
/// argument, when the opposite match is also allowed (strict pack match).
1846+
/// This needs to be cached as deduction is performed during declaration,
1847+
/// and we need the information to be preserved so that it is consistent
1848+
/// during instantiation.
1849+
bool MatchedPackOnParmToNonPackOnArg : 1;
1850+
18441851
protected:
18451852
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
18461853
DeclContext *DC, SourceLocation StartLoc,
18471854
SourceLocation IdLoc,
18481855
ClassTemplateDecl *SpecializedTemplate,
18491856
ArrayRef<TemplateArgument> Args,
1857+
bool MatchedPackOnParmToNonPackOnArg,
18501858
ClassTemplateSpecializationDecl *PrevDecl);
18511859

1852-
explicit ClassTemplateSpecializationDecl(ASTContext &C, Kind DK);
1860+
ClassTemplateSpecializationDecl(ASTContext &C, Kind DK);
18531861

18541862
public:
18551863
friend class ASTDeclReader;
@@ -1859,7 +1867,7 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
18591867
Create(ASTContext &Context, TagKind TK, DeclContext *DC,
18601868
SourceLocation StartLoc, SourceLocation IdLoc,
18611869
ClassTemplateDecl *SpecializedTemplate,
1862-
ArrayRef<TemplateArgument> Args,
1870+
ArrayRef<TemplateArgument> Args, bool MatchedPackOnParmToNonPackOnArg,
18631871
ClassTemplateSpecializationDecl *PrevDecl);
18641872
static ClassTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
18651873
GlobalDeclID ID);
@@ -1930,6 +1938,10 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
19301938
SpecializationKind = TSK;
19311939
}
19321940

1941+
bool hasMatchedPackOnParmToNonPackOnArg() const {
1942+
return MatchedPackOnParmToNonPackOnArg;
1943+
}
1944+
19331945
/// Get the point of instantiation (if any), or null if none.
19341946
SourceLocation getPointOfInstantiation() const {
19351947
return PointOfInstantiation;

clang/include/clang/Sema/Sema.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13499,8 +13499,8 @@ class Sema final : public SemaBase {
1349913499
bool InstantiateClassTemplateSpecialization(
1350013500
SourceLocation PointOfInstantiation,
1350113501
ClassTemplateSpecializationDecl *ClassTemplateSpec,
13502-
TemplateSpecializationKind TSK, bool Complain = true,
13503-
bool PrimaryHasMatchedPackOnParmToNonPackOnArg = false);
13502+
TemplateSpecializationKind TSK, bool Complain,
13503+
bool PrimaryHasMatchedPackOnParmToNonPackOnArg);
1350413504

1350513505
/// Instantiates the definitions of all of the member
1350613506
/// of the given class, which is an instantiation of a class template

clang/lib/AST/ASTImporter.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6321,9 +6321,9 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl(
63216321
updateLookupTableForTemplateParameters(*ToTPList);
63226322
} else { // Not a partial specialization.
63236323
if (GetImportedOrCreateDecl(
6324-
D2, D, Importer.getToContext(), D->getTagKind(), DC,
6325-
*BeginLocOrErr, *IdLocOrErr, ClassTemplate, TemplateArgs,
6326-
PrevDecl))
6324+
D2, D, Importer.getToContext(), D->getTagKind(), DC, *BeginLocOrErr,
6325+
*IdLocOrErr, ClassTemplate, TemplateArgs,
6326+
D->hasMatchedPackOnParmToNonPackOnArg(), PrevDecl))
63276327
return D2;
63286328

63296329
// Update InsertPos, because preceding import calls may have invalidated

clang/lib/AST/DeclTemplate.cpp

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -957,18 +957,20 @@ FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
957957
// ClassTemplateSpecializationDecl Implementation
958958
//===----------------------------------------------------------------------===//
959959

960-
ClassTemplateSpecializationDecl::
961-
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
962-
DeclContext *DC, SourceLocation StartLoc,
963-
SourceLocation IdLoc,
964-
ClassTemplateDecl *SpecializedTemplate,
965-
ArrayRef<TemplateArgument> Args,
966-
ClassTemplateSpecializationDecl *PrevDecl)
960+
ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(
961+
ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC,
962+
SourceLocation StartLoc, SourceLocation IdLoc,
963+
ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
964+
bool MatchedPackOnParmToNonPackOnArg,
965+
ClassTemplateSpecializationDecl *PrevDecl)
967966
: CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
968967
SpecializedTemplate->getIdentifier(), PrevDecl),
969-
SpecializedTemplate(SpecializedTemplate),
970-
TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
971-
SpecializationKind(TSK_Undeclared) {
968+
SpecializedTemplate(SpecializedTemplate),
969+
TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
970+
SpecializationKind(TSK_Undeclared),
971+
MatchedPackOnParmToNonPackOnArg(MatchedPackOnParmToNonPackOnArg) {
972+
assert(DK == Kind::ClassTemplateSpecialization ||
973+
MatchedPackOnParmToNonPackOnArg == false);
972974
}
973975

974976
ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
@@ -977,18 +979,14 @@ ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
977979
SourceLocation(), nullptr, nullptr),
978980
SpecializationKind(TSK_Undeclared) {}
979981

980-
ClassTemplateSpecializationDecl *
981-
ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
982-
DeclContext *DC,
983-
SourceLocation StartLoc,
984-
SourceLocation IdLoc,
985-
ClassTemplateDecl *SpecializedTemplate,
986-
ArrayRef<TemplateArgument> Args,
987-
ClassTemplateSpecializationDecl *PrevDecl) {
988-
auto *Result =
989-
new (Context, DC) ClassTemplateSpecializationDecl(
990-
Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
991-
SpecializedTemplate, Args, PrevDecl);
982+
ClassTemplateSpecializationDecl *ClassTemplateSpecializationDecl::Create(
983+
ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
984+
SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate,
985+
ArrayRef<TemplateArgument> Args, bool MatchedPackOnParmToNonPackOnArg,
986+
ClassTemplateSpecializationDecl *PrevDecl) {
987+
auto *Result = new (Context, DC) ClassTemplateSpecializationDecl(
988+
Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
989+
SpecializedTemplate, Args, MatchedPackOnParmToNonPackOnArg, PrevDecl);
992990
Result->setMayHaveOutOfDateDef(false);
993991

994992
// If the template decl is incomplete, copy the external lexical storage from
@@ -1175,7 +1173,10 @@ ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl(
11751173
ClassTemplatePartialSpecializationDecl *PrevDecl)
11761174
: ClassTemplateSpecializationDecl(
11771175
Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc,
1178-
SpecializedTemplate, Args, PrevDecl),
1176+
// Tracking MatchedPackOnParmToNonPackOnArg for Partial
1177+
// Specializations is not needed.
1178+
SpecializedTemplate, Args, /*MatchedPackOnParmToNonPackOnArg=*/false,
1179+
PrevDecl),
11791180
TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
11801181
if (AdoptTemplateParameterList(Params, this))
11811182
setInvalidDecl();

clang/lib/AST/JSONNodeDumper.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,11 @@ void JSONNodeDumper::VisitRecordDecl(const RecordDecl *RD) {
10031003
void JSONNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *RD) {
10041004
VisitRecordDecl(RD);
10051005

1006+
if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
1007+
if (CTSD->hasMatchedPackOnParmToNonPackOnArg())
1008+
JOS.attribute("strict-pack-match", true);
1009+
}
1010+
10061011
// All other information requires a complete definition.
10071012
if (!RD->isCompleteDefinition())
10081013
return;

clang/lib/AST/TextNodeDumper.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2525,8 +2525,11 @@ void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
25252525
OS << " instantiated_from";
25262526
dumpPointer(Instance);
25272527
}
2528-
if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D))
2528+
if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
25292529
dumpTemplateSpecializationKind(CTSD->getSpecializationKind());
2530+
if (CTSD->hasMatchedPackOnParmToNonPackOnArg())
2531+
OS << " strict-pack-match";
2532+
}
25302533

25312534
dumpNestedNameSpecifier(D->getQualifier());
25322535

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3651,7 +3651,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
36513651
ClassTemplate->getDeclContext(),
36523652
ClassTemplate->getTemplatedDecl()->getBeginLoc(),
36533653
ClassTemplate->getLocation(), ClassTemplate, CTAI.CanonicalConverted,
3654-
nullptr);
3654+
CTAI.MatchedPackOnParmToNonPackOnArg, nullptr);
36553655
ClassTemplate->AddSpecialization(Decl, InsertPos);
36563656
if (ClassTemplate->isOutOfLine())
36573657
Decl->setLexicalDeclContext(ClassTemplate->getLexicalDeclContext());
@@ -8526,7 +8526,8 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
85268526
// this explicit specialization or friend declaration.
85278527
Specialization = ClassTemplateSpecializationDecl::Create(
85288528
Context, Kind, DC, KWLoc, TemplateNameLoc, ClassTemplate,
8529-
CTAI.CanonicalConverted, PrevDecl);
8529+
CTAI.CanonicalConverted, CTAI.MatchedPackOnParmToNonPackOnArg,
8530+
PrevDecl);
85308531
Specialization->setTemplateArgsAsWritten(TemplateArgs);
85318532
SetNestedNameSpecifier(*this, Specialization, SS);
85328533
if (TemplateParameterLists.size() > 0) {
@@ -9869,7 +9870,8 @@ DeclResult Sema::ActOnExplicitInstantiation(
98699870
// this explicit specialization.
98709871
Specialization = ClassTemplateSpecializationDecl::Create(
98719872
Context, Kind, ClassTemplate->getDeclContext(), KWLoc, TemplateNameLoc,
9872-
ClassTemplate, CTAI.CanonicalConverted, PrevDecl);
9873+
ClassTemplate, CTAI.CanonicalConverted,
9874+
CTAI.MatchedPackOnParmToNonPackOnArg, PrevDecl);
98739875
SetNestedNameSpecifier(*this, Specialization, SS);
98749876

98759877
// A MSInheritanceAttr attached to the previous declaration must be

clang/lib/Sema/SemaTemplateDeduction.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3341,8 +3341,6 @@ FinishTemplateArgumentDeduction(
33413341
return ConstraintsNotSatisfied
33423342
? TemplateDeductionResult::ConstraintsNotSatisfied
33433343
: TemplateDeductionResult::SubstitutionFailure;
3344-
if (InstCTAI.MatchedPackOnParmToNonPackOnArg)
3345-
Info.setMatchedPackOnParmToNonPackOnArg();
33463344

33473345
TemplateParameterList *TemplateParams = Template->getTemplateParameters();
33483346
for (unsigned I = 0, E = TemplateParams->size(); I != E; ++I) {

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4038,7 +4038,7 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl(
40384038
ClassTemplateSpecializationDecl::Create(
40394039
SemaRef.Context, D->getTagKind(), Owner, D->getBeginLoc(),
40404040
D->getLocation(), InstClassTemplate, CTAI.CanonicalConverted,
4041-
PrevDecl);
4041+
CTAI.MatchedPackOnParmToNonPackOnArg, PrevDecl);
40424042
InstD->setTemplateArgsAsWritten(InstTemplateArgs);
40434043

40444044
// Add this partial specialization to the set of class template partial

clang/lib/Sema/SemaType.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9399,7 +9399,8 @@ bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
93999399
runWithSufficientStackSpace(Loc, [&] {
94009400
Diagnosed = InstantiateClassTemplateSpecialization(
94019401
Loc, ClassTemplateSpec, TSK_ImplicitInstantiation,
9402-
/*Complain=*/Diagnoser);
9402+
/*Complain=*/Diagnoser,
9403+
ClassTemplateSpec->hasMatchedPackOnParmToNonPackOnArg());
94039404
});
94049405
Instantiated = true;
94059406
}

clang/lib/Serialization/ASTReaderDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2532,6 +2532,7 @@ RedeclarableResult ASTDeclReader::VisitClassTemplateSpecializationDeclImpl(
25322532
D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs);
25332533
D->PointOfInstantiation = readSourceLocation();
25342534
D->SpecializationKind = (TemplateSpecializationKind)Record.readInt();
2535+
D->MatchedPackOnParmToNonPackOnArg = Record.readBool();
25352536

25362537
bool writtenAsCanonicalDecl = Record.readInt();
25372538
if (writtenAsCanonicalDecl) {

clang/lib/Serialization/ASTWriterDecl.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1843,6 +1843,7 @@ void ASTDeclWriter::VisitClassTemplateSpecializationDecl(
18431843
Record.AddTemplateArgumentList(&D->getTemplateArgs());
18441844
Record.AddSourceLocation(D->getPointOfInstantiation());
18451845
Record.push_back(D->getSpecializationKind());
1846+
Record.push_back(D->hasMatchedPackOnParmToNonPackOnArg());
18461847
Record.push_back(D->isCanonicalDecl());
18471848

18481849
if (D->isCanonicalDecl()) {

0 commit comments

Comments
 (0)