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