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