On 5/21/26 11:46 AM, Marek Polacek wrote:
On Thu, May 21, 2026 at 10:49:09AM -0400, Patrick Palka wrote:
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.

I thought we could get there with certain enums (INT_MAX + 1), but
I'm unable to trigger that.  So we would need some exotic platform
where sizeof (short) == sizeof (int) to get the crash.  So, dunno,
maybe it's good as-is.

We might as well have the new local variable record the type of the NOP_EXPR rather than bool. OK with that change.

Jason

Reply via email to