From 1ad95178817e58dd7767f0c8b472ec0b7e46cd45 Mon Sep 17 00:00:00 2001 From: Dan Katz Date: Fri, 12 Jul 2024 13:57:33 -0400 Subject: [PATCH 1/5] Fix assertion failure during operator overload resolution. --- clang/lib/Sema/SemaConcept.cpp | 3 ++- clang/test/SemaCXX/PR98671.cpp | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 clang/test/SemaCXX/PR98671.cpp diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index de24bbe7eb99c..ef531fc61dc7c 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -1743,7 +1743,8 @@ bool Sema::IsAtLeastAsConstrained(NamedDecl *D1, auto IsExpectedEntity = [](const FunctionDecl *FD) { FunctionDecl::TemplatedKind Kind = FD->getTemplatedKind(); return Kind == FunctionDecl::TK_NonTemplate || - Kind == FunctionDecl::TK_FunctionTemplate; + Kind == FunctionDecl::TK_FunctionTemplate || + Kind == FunctionDecl::TK_FunctionTemplateSpecialization; }; const auto *FD2 = dyn_cast(D2); (void)IsExpectedEntity; diff --git a/clang/test/SemaCXX/PR98671.cpp b/clang/test/SemaCXX/PR98671.cpp new file mode 100644 index 0000000000000..696b750759854 --- /dev/null +++ b/clang/test/SemaCXX/PR98671.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -std=c++20 -fsyntax-only %s -verify + +struct S { + operator int(); + + template + operator T(); +}; + + +// Ensure that no assertion is raised when overload resolution fails while +// choosing between an operator function template and an operator function. +constexpr auto r = &S::operator int; +// expected-error@-1 {{initializer of type ''}} From 6c8a48b656d4a0cb8a859a2335e3467467da06aa Mon Sep 17 00:00:00 2001 From: Dan Katz Date: Tue, 16 Jul 2024 11:15:27 -0400 Subject: [PATCH 2/5] Address feedback. --- clang/lib/Sema/SemaConcept.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index ef531fc61dc7c..6f642fabe8835 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -1743,7 +1743,7 @@ bool Sema::IsAtLeastAsConstrained(NamedDecl *D1, auto IsExpectedEntity = [](const FunctionDecl *FD) { FunctionDecl::TemplatedKind Kind = FD->getTemplatedKind(); return Kind == FunctionDecl::TK_NonTemplate || - Kind == FunctionDecl::TK_FunctionTemplate || + Kind == FunctionDecl::TK_MemberSpecialization || Kind == FunctionDecl::TK_FunctionTemplateSpecialization; }; const auto *FD2 = dyn_cast(D2); From ed648686c56f13dfccc56e50b0cbbb309a2f482e Mon Sep 17 00:00:00 2001 From: Dan Katz Date: Mon, 22 Jul 2024 06:56:53 -0400 Subject: [PATCH 3/5] Change approach to fixing this. --- clang/lib/Sema/SemaConcept.cpp | 3 +-- clang/lib/Sema/SemaTemplateDeduction.cpp | 23 +++++++++++++++++------ clang/test/SemaCXX/PR98671.cpp | 18 ++++++++++++++++-- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index 6f642fabe8835..de24bbe7eb99c 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -1743,8 +1743,7 @@ bool Sema::IsAtLeastAsConstrained(NamedDecl *D1, auto IsExpectedEntity = [](const FunctionDecl *FD) { FunctionDecl::TemplatedKind Kind = FD->getTemplatedKind(); return Kind == FunctionDecl::TK_NonTemplate || - Kind == FunctionDecl::TK_MemberSpecialization || - Kind == FunctionDecl::TK_FunctionTemplateSpecialization; + Kind == FunctionDecl::TK_FunctionTemplate; }; const auto *FD2 = dyn_cast(D2); (void)IsExpectedEntity; diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index e9705ec43d86c..814d7e3f1f009 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -5805,12 +5805,23 @@ FunctionDecl *Sema::getMoreConstrainedFunction(FunctionDecl *FD1, FunctionDecl *FD2) { assert(!FD1->getDescribedTemplate() && !FD2->getDescribedTemplate() && "not for function templates"); - FunctionDecl *F1 = FD1; - if (FunctionDecl *MF = FD1->getInstantiatedFromMemberFunction()) - F1 = MF; - FunctionDecl *F2 = FD2; - if (FunctionDecl *MF = FD2->getInstantiatedFromMemberFunction()) - F2 = MF; + + auto getTemplatePattern = [](FunctionDecl *FD) { + // Specializations of conversion function templates are believed to be the + // only case where a function template specialization reaches here. + assert(!FD->isFunctionTemplateSpecialization() || + isa(FD)); + + if (FunctionDecl *MF = FD->getInstantiatedFromMemberFunction()) + return MF; + else if (FunctionTemplateDecl *FTD = FD->getPrimaryTemplate()) + return FTD->getTemplatedDecl(); + + return FD; + }; + FunctionDecl *F1 = getTemplatePattern(FD1); + FunctionDecl *F2 = getTemplatePattern(FD2); + llvm::SmallVector AC1, AC2; F1->getAssociatedConstraints(AC1); F2->getAssociatedConstraints(AC2); diff --git a/clang/test/SemaCXX/PR98671.cpp b/clang/test/SemaCXX/PR98671.cpp index 696b750759854..f505186735885 100644 --- a/clang/test/SemaCXX/PR98671.cpp +++ b/clang/test/SemaCXX/PR98671.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -std=c++20 -fsyntax-only %s -verify -struct S { +struct S1 { operator int(); template @@ -10,5 +10,19 @@ struct S { // Ensure that no assertion is raised when overload resolution fails while // choosing between an operator function template and an operator function. -constexpr auto r = &S::operator int; +constexpr auto r = &S1::operator int; // expected-error@-1 {{initializer of type ''}} + + +template +struct S2 { + template + S2(U={}) requires (sizeof(T) > 0) {} + // expected-note@-1 {{candidate constructor}} + + template + S2(U={}) requires (true) {} + // expected-note@-1 {{candidate constructor}} +}; + +S2 s; // expected-error {{call to constructor of 'S2' is ambiguous}} From 8debcdb2efe6c33ae9dab27e4227763ee8ae5f92 Mon Sep 17 00:00:00 2001 From: Dan Katz Date: Thu, 25 Jul 2024 12:09:19 -0400 Subject: [PATCH 4/5] Addressing feedback. --- clang/lib/Sema/SemaTemplateDeduction.cpp | 28 ++++++++++-------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 814d7e3f1f009..ec951d5ac06db 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -5805,22 +5805,18 @@ FunctionDecl *Sema::getMoreConstrainedFunction(FunctionDecl *FD1, FunctionDecl *FD2) { assert(!FD1->getDescribedTemplate() && !FD2->getDescribedTemplate() && "not for function templates"); - - auto getTemplatePattern = [](FunctionDecl *FD) { - // Specializations of conversion function templates are believed to be the - // only case where a function template specialization reaches here. - assert(!FD->isFunctionTemplateSpecialization() || - isa(FD)); - - if (FunctionDecl *MF = FD->getInstantiatedFromMemberFunction()) - return MF; - else if (FunctionTemplateDecl *FTD = FD->getPrimaryTemplate()) - return FTD->getTemplatedDecl(); - - return FD; - }; - FunctionDecl *F1 = getTemplatePattern(FD1); - FunctionDecl *F2 = getTemplatePattern(FD2); + assert(!FD1->isFunctionTemplateSpecialization() || + isa(FD1)); + assert(!FD2->isFunctionTemplateSpecialization() || + isa(FD2)); + + FunctionDecl *F1 = FD1; + if (FunctionDecl *P = FD1->getTemplateInstantiationPattern(false)) + F1 = P; + + FunctionDecl *F2 = FD2; + if (FunctionDecl *P = FD2->getTemplateInstantiationPattern(false)) + F2 = P; llvm::SmallVector AC1, AC2; F1->getAssociatedConstraints(AC1); From eaf3b5a177822154df8bf5de24ed2323defea620 Mon Sep 17 00:00:00 2001 From: Dan Katz Date: Mon, 12 Aug 2024 10:16:34 -0400 Subject: [PATCH 5/5] Add a release note. --- clang/docs/ReleaseNotes.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 6796a619ba97f..39e1b0fcb09bb 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -217,6 +217,8 @@ Bug Fixes to C++ Support - Clang now preserves the unexpanded flag in a lambda transform used for pack expansion. (#GH56852), (#GH85667), (#GH99877). - Fixed a bug when diagnosing ambiguous explicit specializations of constrained member functions. +- Fixed an assertion failure when selecting a function from an overload set that includes a + specialization of a conversion function template. Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^