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.

> +           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