builtin_generic_overflow.c (1398B)
1 /* Type-generic overflow builtins (__builtin_add/sub/mul_overflow). The 2 * operation type is inferred from the result pointer's pointee, dispatching to 3 * the same per-type intrinsics as the explicit __builtin_smull_overflow family. 4 * kit's own source (src/cg/control.c cg_checked_scaled_offset) uses these, so 5 * they must self-host. Returns the count of passing checks (expect 7). The 6 * signed-`long` overflow check uses __LONG_MAX__ (LONG_MAX*2 overflows `long` 7 * under both LP64 and the ILP32 arm32/rv32 data model), so the case is 8 * data-model-agnostic. */ 9 10 int test_main(void) { 11 int ok = 0; 12 long lp; 13 int ip; 14 unsigned up; 15 unsigned long ulp; 16 17 /* signed mul, no overflow */ 18 if (!__builtin_mul_overflow(3L, 4L, &lp) && lp == 12L) ok++; 19 /* signed mul, overflow (LONG_MAX*2 overflows `long` under LP64 and ILP32) */ 20 if (__builtin_mul_overflow((long)__LONG_MAX__, 2L, &lp)) ok++; 21 /* signed add, no overflow */ 22 if (!__builtin_add_overflow(100, 23, &ip) && ip == 123) ok++; 23 /* signed int add, overflow */ 24 if (__builtin_add_overflow((int)0x7fffffff, 1, &ip)) ok++; 25 /* unsigned sub, wrap (overflow) */ 26 if (__builtin_sub_overflow(0u, 1u, &up)) ok++; 27 /* unsigned sub, no overflow */ 28 if (!__builtin_sub_overflow(10u, 3u, &up) && up == 7u) ok++; 29 /* unsigned long mul, no overflow */ 30 if (!__builtin_mul_overflow(6ul, 7ul, &ulp) && ulp == 42ul) ok++; 31 32 return ok; 33 }