refactor(ast2ir): 移除废弃的ABI依赖并优化类型转换处理

移除了对scc_abi包的依赖,将相关头文件从libs/abi移动到libs/ast2ir目录下。
重构了基本类型解析功能,将parse_base_type函数提取为独立的
scc_ast2ir_parse_base_type实现,并支持有符号/无符号类型区分。

feat(ast2ir): 实现整数常量表达式求值器

新增了完整的整数常量表达式求值功能,支持C11标准中的常量表达式规则,
包括字面量、标识符、sizeof/_Alignof、一元/二元运算、条件表达式和
类型转换等操作。该功能用于数组大小和枚举值的编译期计算验证。

refactor(ast2ir): 完善类型提升和算术转换机制

改进了整数提升和寻常算术转换的实现,修复了移位操作的符号处理问题,
添加了无符号比较操作的支持,增强了类型安全检查,统一了错误处理流程。

fix(ast2ir): 修复赋值表达式返回值和数组大小计算问题

修正了赋值表达式的返回值处理,确保返回右侧值而不是存储指令引用。
使用新的常量表达式求值器替代原有的硬编码数组大小计算,提高了
数组声明的正确性。
This commit is contained in:
zzy
2026-05-31 17:30:22 +08:00
parent c4467b8420
commit d2eafa9dc6
27 changed files with 2579 additions and 218 deletions

View File

@@ -0,0 +1,184 @@
#include <ap.h>
#include <stdio.h>
#include <string.h>
#include <utest/acutest.h>
/*
* 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},
};