On Thu, 21 May 2026, Marek Polacek wrote:

> On Thu, May 21, 2026 at 10:28:37AM -0400, Patrick Palka wrote:
> > Tested on x86_64-pc-linux-gnu, does this look OK for trunk/16?
> > 
> > -- >8 --
> > 
> > When a user operator<=> returns an integral type smaller than int, the
> > rewritten form of x @ y contains an integer promotion: (int)(x <=> y) @ 0.
> > 
> > This patch teaches build_min_non_dep_op_overload to look through and
> > preserve this implicit cast.
> > 
> >     PR c++/125378
> > 
> > gcc/cp/ChangeLog:
> > 
> >     * tree.cc (build_min_non_dep_op_overload): Handle comparison
> >     operator expressions rewritten from a <=> that contain an
> >     integer promotion.
> > 
> > gcc/testsuite/ChangeLog:
> > 
> >     * g++.dg/lookup/operator-8b.C: New test.
> >     * g++.dg/lookup/operator-8c.C: New test.
> >     * g++.dg/lookup/operator-9a.C: New test.
> >     * g++.dg/lookup/operator-9b.C: New test.
> > ---
> >  gcc/cp/tree.cc                            | 13 ++++++++
> >  gcc/testsuite/g++.dg/lookup/operator-8b.C | 40 +++++++++++++++++++++++
> >  gcc/testsuite/g++.dg/lookup/operator-8c.C | 40 +++++++++++++++++++++++
> >  gcc/testsuite/g++.dg/lookup/operator-9a.C | 19 +++++++++++
> >  gcc/testsuite/g++.dg/lookup/operator-9b.C | 19 +++++++++++
> >  5 files changed, 131 insertions(+)
> >  create mode 100644 gcc/testsuite/g++.dg/lookup/operator-8b.C
> >  create mode 100644 gcc/testsuite/g++.dg/lookup/operator-8c.C
> >  create mode 100644 gcc/testsuite/g++.dg/lookup/operator-9a.C
> >  create mode 100644 gcc/testsuite/g++.dg/lookup/operator-9b.C
> > 
> > diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
> > index 02a62f78511c..8af3bd6f4641 100644
> > --- a/gcc/cp/tree.cc
> > +++ b/gcc/cp/tree.cc
> > @@ -3855,6 +3855,17 @@ build_min_non_dep_op_overload (enum tree_code op,
> >       tree spaceship_non_dep = (TREE_CODE (non_dep) == CALL_EXPR
> >                                 ? CALL_EXPR_ARG (non_dep, reversed ? 1 : 0)
> >                                 : TREE_OPERAND (non_dep, reversed ? 1 : 0));
> > +
> > +     bool int_promotion = false;
> > +     if (TREE_CODE (spaceship_non_dep) == NOP_EXPR)
> > +       {
> > +         gcc_checking_assert (TREE_CODE (non_dep) != CALL_EXPR);
> > +         gcc_checking_assert (TREE_TYPE (spaceship_non_dep)
> > +                              == integer_type_node);
> 
> It seems to me this should also check unsigned_type_node for the
> rare case we get promotion to unsigned int.

I wasn't able to come up with a testcase where we get an unsigned int
promotion in the rewritten form.  Even if operator<=> returns e.g.
unsigned char we still always see an int promotion it seems.

> 
> > +         spaceship_non_dep = TREE_OPERAND (spaceship_non_dep, 0);
> > +         int_promotion = true;
> > +       }
> > +
> >       gcc_checking_assert (TREE_CODE (spaceship_non_dep) == CALL_EXPR);
> >       tree spaceship_op0 = va_arg (p, tree);
> >       tree spaceship_op1 = va_arg (p, tree);
> > @@ -3877,6 +3888,8 @@ build_min_non_dep_op_overload (enum tree_code op,
> >         {
> >           gcc_checking_assert (COMPARISON_CLASS_P (non_dep)
> >                                || TREE_CODE (non_dep) == SPACESHIP_EXPR);
> > +         if (int_promotion)
> > +           op0 = build_nop (integer_type_node, op0);
> 
> And if so, this should also use unsigned_type_node.
> 
> Marek
> 
> 

Reply via email to