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