https://github.com/offsetof updated https://github.com/llvm/llvm-project/pull/132830
>From e458a6b79f560e803bdce414ea35f147ee4ce39d Mon Sep 17 00:00:00 2001 From: offsetof <offse...@mailo.com> Date: Mon, 24 Mar 2025 21:06:44 +0000 Subject: [PATCH 1/4] [clang] Fix overload resolution ranking of inherited constructors Take parameter types of candidate constructors into account when deciding whether to apply the tiebreaker. --- clang/docs/ReleaseNotes.rst | 3 +++ clang/lib/Sema/SemaOverload.cpp | 17 ++++++++--------- clang/test/CXX/drs/cwg22xx.cpp | 14 ++++++++++++++ 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index f919b66dd0e41..a3d882312056c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -358,6 +358,9 @@ Bug Fixes to C++ Support - Fixed a Clang regression in C++20 mode where unresolved dependent call expressions were created inside non-dependent contexts (#GH122892) - Clang now emits the ``-Wunused-variable`` warning when some structured bindings are unused and the ``[[maybe_unused]]`` attribute is not applied. (#GH125810) +- Overload resolution tiebreaker for inherited constructors is now only + applied if their parameters have the same type, as required by the C++ + standard. (#GH121331) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 6d8006b35dcf4..f35d272b470cb 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -40,6 +40,7 @@ #include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Casting.h" #include <algorithm> #include <cassert> #include <cstddef> @@ -10724,15 +10725,13 @@ bool clang::isBetterOverloadCandidate( // -- F1 is a constructor for a class D, F2 is a constructor for a base // class B of D, and for all arguments the corresponding parameters of // F1 and F2 have the same type. - // FIXME: Implement the "all parameters have the same type" check. - bool Cand1IsInherited = - isa_and_nonnull<ConstructorUsingShadowDecl>(Cand1.FoundDecl.getDecl()); - bool Cand2IsInherited = - isa_and_nonnull<ConstructorUsingShadowDecl>(Cand2.FoundDecl.getDecl()); - if (Cand1IsInherited != Cand2IsInherited) - return Cand2IsInherited; - else if (Cand1IsInherited) { - assert(Cand2IsInherited); + if (isa_and_nonnull<CXXConstructorDecl>(Cand1.Function) && + isa_and_nonnull<CXXConstructorDecl>(Cand2.Function) && + llvm::equal(Cand1.Function->parameters().take_front(NumArgs), + Cand2.Function->parameters().take_front(NumArgs), + [&](ParmVarDecl *P1, ParmVarDecl *P2) { + return S.Context.hasSameUnqualifiedType(P1->getType(), P2->getType()); + })) { auto *Cand1Class = cast<CXXRecordDecl>(Cand1.Function->getDeclContext()); auto *Cand2Class = cast<CXXRecordDecl>(Cand2.Function->getDeclContext()); if (Cand1Class->isDerivedFrom(Cand2Class)) diff --git a/clang/test/CXX/drs/cwg22xx.cpp b/clang/test/CXX/drs/cwg22xx.cpp index 8c8ad9f7f74ee..43bab3da171e4 100644 --- a/clang/test/CXX/drs/cwg22xx.cpp +++ b/clang/test/CXX/drs/cwg22xx.cpp @@ -169,6 +169,20 @@ B b; // since-cxx11-error@-1 {{call to implicitly-deleted default constructor of 'B'}} // since-cxx11-note@#cwg2273-B {{default constructor of 'B' is implicitly deleted because base class 'A' has a deleted default constructor}} // since-cxx11-note@#cwg2273-A {{'A' has been explicitly marked deleted here}} + +struct X { + X(float); // since-cxx11-note {{candidate inherited constructor}} + X(void*, int = 0) = delete; +}; + +struct Y : X { + using X::X; // since-cxx11-note {{constructor from base class 'X' inherited here}} + Y(double); // since-cxx11-note {{candidate constructor}} + Y(void* const, long = 1); +}; + +Y y = 1; // since-cxx11-error {{conversion from 'int' to 'Y' is ambiguous}} +Y z = nullptr; #endif } // namespace cwg2273 >From bd15fc45015c79c21c62295677644e2f1d72fbe4 Mon Sep 17 00:00:00 2001 From: offsetof <offse...@mailo.com> Date: Mon, 24 Mar 2025 21:26:58 +0000 Subject: [PATCH 2/4] fixup! [clang] Fix overload resolution ranking of inherited constructors Fix formatting --- clang/lib/Sema/SemaOverload.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index f35d272b470cb..8e594753d261e 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -10730,7 +10730,8 @@ bool clang::isBetterOverloadCandidate( llvm::equal(Cand1.Function->parameters().take_front(NumArgs), Cand2.Function->parameters().take_front(NumArgs), [&](ParmVarDecl *P1, ParmVarDecl *P2) { - return S.Context.hasSameUnqualifiedType(P1->getType(), P2->getType()); + return S.Context.hasSameUnqualifiedType(P1->getType(), + P2->getType()); })) { auto *Cand1Class = cast<CXXRecordDecl>(Cand1.Function->getDeclContext()); auto *Cand2Class = cast<CXXRecordDecl>(Cand2.Function->getDeclContext()); >From 9eb3b12fcf4d9c779c192d5150ca73729b94f6fb Mon Sep 17 00:00:00 2001 From: offsetof <offse...@mailo.com> Date: Tue, 25 Mar 2025 16:00:31 +0000 Subject: [PATCH 3/4] fixup! [clang] Fix overload resolution ranking of inherited constructors --- clang/lib/Sema/SemaOverload.cpp | 1 - clang/test/CXX/drs/cwg22xx.cpp | 18 +++++++++++------- clang/www/cxx_dr_status.html | 4 ++-- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 8e594753d261e..7aba7da9b7912 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -40,7 +40,6 @@ #include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/Support/Casting.h" #include <algorithm> #include <cassert> #include <cstddef> diff --git a/clang/test/CXX/drs/cwg22xx.cpp b/clang/test/CXX/drs/cwg22xx.cpp index 43bab3da171e4..3f7a19ccd0040 100644 --- a/clang/test/CXX/drs/cwg22xx.cpp +++ b/clang/test/CXX/drs/cwg22xx.cpp @@ -155,7 +155,7 @@ const D &d3(c); // FIXME ill-formed #endif } // namespace cwg2267 -namespace cwg2273 { // cwg2273: 3.3 +namespace cwg2273 { // cwg2273: 21 #if __cplusplus >= 201103L struct A { A(int = 0) = delete; // #cwg2273-A @@ -171,22 +171,26 @@ B b; // since-cxx11-note@#cwg2273-A {{'A' has been explicitly marked deleted here}} struct X { - X(float); // since-cxx11-note {{candidate inherited constructor}} + X(float); // #cwg2273-X X(void*, int = 0) = delete; }; struct Y : X { - using X::X; // since-cxx11-note {{constructor from base class 'X' inherited here}} - Y(double); // since-cxx11-note {{candidate constructor}} + using X::X; // #cwg2273-Y1 + Y(double); // #cwg2273-Y2 Y(void* const, long = 1); }; -Y y = 1; // since-cxx11-error {{conversion from 'int' to 'Y' is ambiguous}} +Y y = 1; +// since-cxx11-error@-1 {{conversion from 'int' to 'Y' is ambiguous}} +// since-cxx11-note@#cwg2273-X {{candidate inherited constructor}} +// since-cxx11-note@#cwg2273-Y1 {{constructor from base class 'X' inherited here}} +// since-cxx11-note@#cwg2273-Y2 {{candidate constructor}} Y z = nullptr; #endif } // namespace cwg2273 -namespace cwg2277 { // cwg2277: partial +namespace cwg2277 { // cwg2277: 21 #if __cplusplus >= 201103L struct A { A(int, int = 0); @@ -202,7 +206,7 @@ struct B : A { void g() { B b{0}; - b.f(0); // FIXME: this is well-formed for the same reason as initialization of 'b' above + b.f(0); // since-cxx11-error@-1 {{call to member function 'f' is ambiguous}} // since-cxx11-note@#cwg2277-A-f {{candidate function}} // since-cxx11-note@#cwg2277-B-f {{candidate function}} diff --git a/clang/www/cxx_dr_status.html b/clang/www/cxx_dr_status.html index 16a9b26052f87..0df2d1a9996d0 100755 --- a/clang/www/cxx_dr_status.html +++ b/clang/www/cxx_dr_status.html @@ -13469,7 +13469,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> <td><a href="https://cplusplus.github.io/CWG/issues/2273.html">2273</a></td> <td>CD5</td> <td>Inheriting constructors vs implicit default constructor</td> - <td class="full" align="center">Clang 3.3</td> + <td class="unreleased" align="center">Clang 21</td> </tr> <tr id="2274"> <td><a href="https://cplusplus.github.io/CWG/issues/2274.html">2274</a></td> @@ -13493,7 +13493,7 @@ <h2 id="cxxdr">C++ defect report implementation status</h2> <td><a href="https://cplusplus.github.io/CWG/issues/2277.html">2277</a></td> <td>CD5</td> <td>Ambiguity inheriting constructors with default arguments</td> - <td class="partial" align="center">Partial</td> + <td class="unreleased" align="center">Clang 21</td> </tr> <tr id="2278"> <td><a href="https://cplusplus.github.io/CWG/issues/2278.html">2278</a></td> >From 5a1f4c142b3e4044135494322083e41e4863df93 Mon Sep 17 00:00:00 2001 From: offsetof <offse...@mailo.com> Date: Mon, 31 Mar 2025 16:30:55 +0000 Subject: [PATCH 4/4] fixup! [clang] Fix overload resolution ranking of inherited constructors --- clang/test/CXX/drs/cwg22xx.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/clang/test/CXX/drs/cwg22xx.cpp b/clang/test/CXX/drs/cwg22xx.cpp index 3f7a19ccd0040..01ec6db553939 100644 --- a/clang/test/CXX/drs/cwg22xx.cpp +++ b/clang/test/CXX/drs/cwg22xx.cpp @@ -173,12 +173,17 @@ B b; struct X { X(float); // #cwg2273-X X(void*, int = 0) = delete; + X(int, const int*) = delete; + X(unsigned, int()) = delete; }; struct Y : X { using X::X; // #cwg2273-Y1 Y(double); // #cwg2273-Y2 Y(void* const, long = 1); + using IA = int[42]; + Y(int, const IA); + Y(unsigned, int (*)(void)); }; Y y = 1; @@ -187,6 +192,8 @@ Y y = 1; // since-cxx11-note@#cwg2273-Y1 {{constructor from base class 'X' inherited here}} // since-cxx11-note@#cwg2273-Y2 {{candidate constructor}} Y z = nullptr; +Y ya(1, nullptr); +Y yf(1u, nullptr); #endif } // namespace cwg2273 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits