On 8/8/24 1:00 PM, Patrick Palka wrote:
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for trunk/14?-- >8 -- This implements the inherited vs non-inherited guide tiebreaker specified by P2582R1. In order to track inherited-ness of a guide it seems natural to reuse the lang_decl_fn::context field that already tracks inherited-ness of a constructor. This patch also works around CLASSTYPE_CONSTRUCTORS apparently not always containing all inherited constructors, by iterating over TYPE_FIELDS instead. This patch also makes us recognize another written form of inherited constructor, 'using Base<T>::Base::Base' whose USING_DECL_SCOPE is a TYPENAME_TYPE. PR c++/116276 gcc/cp/ChangeLog: * call.cc (joust): Implement P2582R1 inherited vs non-inherited guide tiebreaker. * cp-tree.h (lang_decl_fn::context): Document usage in deduction_guide_p FUNCTION_DECLs. (inherited_guide_p): Declare. * pt.cc (inherited_guide_p): Define. (set_inherited_guide_context): Define. (alias_ctad_tweaks): Use set_inherited_guide_context. (inherited_ctad_tweaks): Recognize some inherited constructors whose scope is a TYPENAME_TYPE. (ctor_deduction_guides_for): For C++23 inherited CTAD, loop over TYPE_FIELDS instead of using CLASSTYPE_CONSTRUCTORS to recognize all relevant using-decls. gcc/testsuite/ChangeLog: * g++.dg/cpp23/class-deduction-inherited4.C: Extend test. * g++.dg/cpp23/class-deduction-inherited5.C: New test. --- gcc/cp/call.cc | 22 +++++++++ gcc/cp/cp-tree.h | 8 +++- gcc/cp/pt.cc | 45 +++++++++++++++---- .../g++.dg/cpp23/class-deduction-inherited4.C | 15 ++++++- .../g++.dg/cpp23/class-deduction-inherited5.C | 25 +++++++++++ 5 files changed, 103 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp23/class-deduction-inherited5.C diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index a75e2e5e3af..3287f77b59b 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -13261,6 +13261,28 @@ joust (struct z_candidate *cand1, struct z_candidate *cand2, bool warn, else if (cand2->rewritten ()) return 1;+ /* F1 and F2 are generated from class template argument deduction for a class+ D, and F2 is generated from inheriting constructors from a base class of D + while F1 is not, and for each explicit function argument, the corresponding + parameters of F1 and F2 are either both ellipses or have the same type */ + if (deduction_guide_p (cand1->fn)) + { + bool inherited1 = inherited_guide_p (cand1->fn); + bool inherited2 = inherited_guide_p (cand2->fn); + if (int diff = inherited2 - inherited1) + { + for (i = 0; i < len; ++i) + { + conversion *t1 = cand1->convs[i + off1]; + conversion *t2 = cand2->convs[i + off2]; + if (!same_type_p (t1->type, t2->type))
I'm not sure this comparison distinguishes between ellipse and non-ellipse? There doesn't seem to be a testcase for that.
Jason
