"with enumeration type %qT is deprecated",
type0, type1);
return;
+ case SPACESHIP_EXPR:
+ /* This is invalid, don't warn. */
+ return;
default:
if (enum_first_p)
warning_at (loc, opt, "arithmetic between enumeration type %qT "
arithmetic conversions are applied to the operands." So we don't do
arithmetic conversions if the operands both have enumeral type. */
result_type = NULL_TREE;
+ else if ((orig_code0 == ENUMERAL_TYPE && orig_code1 == REAL_TYPE)
+ || (orig_code0 == REAL_TYPE && orig_code1 == ENUMERAL_TYPE))
+ /* [depr.arith.conv.enum]: Three-way comparisons between such operands
+ [where one is of enumeration type and the other is of a different
+ enumeration type or a floating-point type] are ill-formed. */
+ result_type = NULL_TREE;
if (result_type)
{
type to a floating point type, the program is ill-formed. */
bool ok = true;
if (TREE_CODE (result_type) == REAL_TYPE
- && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (orig_op0)))
+ && CP_INTEGRAL_TYPE_P (orig_type0))
/* OK */;
else if (!check_narrowing (result_type, orig_op0, complain))
ok = false;
if (TREE_CODE (result_type) == REAL_TYPE
- && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (orig_op1)))
+ && CP_INTEGRAL_TYPE_P (orig_type1))
/* OK */;
else if (!check_narrowing (result_type, orig_op1, complain))
ok = false;
r += b ? d : u1; // { dg-warning "conditional expression between" "" { target c++20 } }
r += b ? u1 : d; // { dg-warning "conditional expression between" "" { target c++20 } }
- // FIXME should be error
- // e1 <=> d;
-
d += e1; // { dg-warning "arithmetic between floating-point type .double. and enumeration type .E1." "" { target c++20 } }
d = e1;
--- /dev/null
+// { dg-do compile { target c++20 } }
+// Test [depr.arith.conv.enum] for <=>.
+
+#include <compare>
+
+enum E1 { e } e1;
+enum E2 { f } e2;
+static double d;
+
+void
+g ()
+{
+ void(e1 <=> e);
+ e1 <=> d; // { dg-error "invalid operands of types .E1. and .double." }
+ d <=> e1; // { dg-error "invalid operands of types .double. and .E1." }
+ e <=> d; // { dg-error "invalid operands of types .E1. and .double." }
+ d <=> e; // { dg-error "invalid operands of types .double. and .E1." }
+
+ e <=> f; // { dg-error "invalid operands of types .E1. and .E2." }
+ f <=> e; // { dg-error "invalid operands of types .E2. and .E1." }
+ e1 <=> e2; // { dg-error "invalid operands of types .E1. and .E2." }
+ e2 <=> e1; // { dg-error "invalid operands of types .E2. and .E1." }
+}