#include #include #include #include /* * Panic / overflow tests — each test calls SCC_AP_PANIC which aborts the * process. Run this file separately from the normal tests. */ /* ---------- helper: attempt an operation and report result ---------- */ #define TRY_PANIC(call, label) \ do { \ fprintf(stderr, " " label " ... "); \ call; \ fprintf(stderr, "FAIL (no panic)\n"); \ TEST_CHECK(0 && "expected panic"); \ } while (0) void test_add_overflow_positive(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_from_string(&a, "9223372036854775807", -1, 10); scc_ap_set_int(&b, 1); TRY_PANIC(scc_ap_add(&r, &a, &b), "INTPTR_MAX + 1"); } void test_add_overflow_negative(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_from_string(&a, "-9223372036854775808", -1, 10); scc_ap_set_int(&b, -1); TRY_PANIC(scc_ap_add(&r, &a, &b), "INTPTR_MIN + (-1)"); } void test_mul_overflow(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_from_string(&a, "4611686018427387904", -1, 10); /* INT64_MAX/2 + 1 */ scc_ap_set_int(&b, 2); TRY_PANIC(scc_ap_mul(&r, &a, &b), "(INT64_MAX/2+1) * 2"); } void test_div_by_zero(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 1); scc_ap_set_int(&b, 0); TRY_PANIC(scc_ap_div(&r, &a, &b), "1 / 0"); } void test_mod_by_zero(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 1); scc_ap_set_int(&b, 0); TRY_PANIC(scc_ap_mod(&r, &a, &b), "1 % 0"); } void test_from_string_overflow(void) { scc_ap_t ap; scc_ap_init(&ap); TRY_PANIC(scc_ap_from_string(&ap, "18446744073709551615", -1, 10), "UINT64_MAX as string"); } void test_set_digit_overflow(void) { scc_ap_t ap; scc_ap_init(&ap); TRY_PANIC(scc_ap_set_digit(&ap, (scc_ap_digit)18446744073709551615ULL), "set_digit(UINT64_MAX)"); } void test_sub_underflow(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_from_string(&a, "-9223372036854775808", -1, 10); scc_ap_set_int(&b, 1); TRY_PANIC(scc_ap_sub(&r, &a, &b), "INTPTR_MIN - 1"); } void test_div_overflow(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_from_string(&a, "-9223372036854775808", -1, 10); scc_ap_set_int(&b, -1); TRY_PANIC(scc_ap_div(&r, &a, &b), "INTPTR_MIN / -1"); } void test_mod_overflow(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_from_string(&a, "-9223372036854775808", -1, 10); scc_ap_set_int(&b, -1); TRY_PANIC(scc_ap_mod(&r, &a, &b), "INTPTR_MIN % -1"); } void test_mul_overflow_neg_limit(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_from_string(&a, "-9223372036854775808", -1, 10); scc_ap_set_int(&b, 2); TRY_PANIC(scc_ap_mul(&r, &a, &b), "INTPTR_MIN * 2"); } void test_with_bits_overflow(void) { scc_ap_t ap; scc_ap_init(&ap); TRY_PANIC(scc_ap_with_bits(&ap, 65), "with_bits(65)"); } /* ---------- shift overflow tests ---------- */ void test_shl_overflow(void) { scc_ap_t a, r; scc_ap_init(&a); scc_ap_init(&r); scc_ap_from_string(&a, "4611686018427387904", -1, 10); /* INT64_MAX/2+1 */ TRY_PANIC(scc_ap_shl(&r, &a, 1), "(INT64_MAX/2+1) << 1"); } void test_shl_shift_ge_64(void) { scc_ap_t a, r; scc_ap_init(&a); scc_ap_init(&r); scc_ap_set_int(&a, 1); TRY_PANIC(scc_ap_shl(&r, &a, 64), "1 << 64"); } void test_shr_shift_ge_64(void) { scc_ap_t a, r; scc_ap_init(&a); scc_ap_init(&r); scc_ap_set_int(&a, 1); TRY_PANIC(scc_ap_shr(&r, &a, 64), "1 >> 64"); } void test_lshr_shift_ge_64(void) { scc_ap_t a, r; scc_ap_init(&a); scc_ap_init(&r); scc_ap_set_int(&a, 1); TRY_PANIC(scc_ap_lshr(&r, &a, 64), "1 lshr 64"); } TEST_LIST = { {"test_add_overflow_positive", test_add_overflow_positive}, {"test_add_overflow_negative", test_add_overflow_negative}, {"test_mul_overflow", test_mul_overflow}, {"test_mul_overflow_neg_limit", test_mul_overflow_neg_limit}, {"test_div_by_zero", test_div_by_zero}, {"test_div_overflow", test_div_overflow}, {"test_mod_by_zero", test_mod_by_zero}, {"test_mod_overflow", test_mod_overflow}, {"test_sub_underflow", test_sub_underflow}, {"test_from_string_overflow", test_from_string_overflow}, {"test_set_digit_overflow", test_set_digit_overflow}, {"test_with_bits_overflow", test_with_bits_overflow}, /* shift overflow */ {"test_shl_overflow", test_shl_overflow}, {"test_shl_shift_ge_64", test_shl_shift_ge_64}, {"test_shr_shift_ge_64", test_shr_shift_ge_64}, {"test_lshr_shift_ge_64", test_lshr_shift_ge_64}, {nullptr, nullptr}, };