271-mixed-sign-cmp.c (981B)
1 /* tests/cc/271-mixed-sign-cmp.c — comparing a signed value to an 2 * unsigned value of the same rank. C's usual-arithmetic-conversions 3 * relabel both as the unsigned type; with a sign-extended canonical 4 * slot for the signed operand the high bits leak into the 64-bit 5 * compare and corrupt the result. Returns 0 when correct. */ 6 int main(void) { 7 int i = -1; /* slot = 0xFFFFFFFFFFFFFFFF */ 8 unsigned int u = 0xFFFFFFFFu; /* slot = 0x00000000FFFFFFFF */ 9 /* Per C: i is converted to (unsigned)i = 0xFFFFFFFFu; the equality 10 * must hold. With the bug, eq compares the raw 64-bit slots and 11 * the test fails. */ 12 if (i != u) return 1; 13 if (!(i == u)) return 2; 14 /* Same idea for relational: (unsigned)-1 < 1 must be false. The 15 * declared unsigned variable forces the codegen path even though 16 * the parser may not preserve the literal U suffix. */ 17 unsigned int one = 1; 18 if (i < one) return 3; 19 return 0; 20 }