fix: P1审查修复 — error.c arena化 + Self类型解析 + trait查找加固 + 缓冲区安全

P1-①: error_init/add 从 malloc/realloc/strdup 改为 arena_alloc/arena_strdup
P1-②: impl 方法中 Self 类型在 sema 解析为实际结构体名
P1-③: trait 方法 fallback 增加前缀校验(strncmp),method_name 统一更新
P1-④: codegen args[16] 增加溢出检查,移除 parser 未使用的 mods/uses 数组
新增: 36_self_type.l 集成测试(Self 类型 + trait 方法)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-06 17:09:28 +08:00
parent 17c19fd9b9
commit 466be76fd8
9 changed files with 99 additions and 56 deletions
+24 -4
View File
@@ -558,19 +558,20 @@ static void analyze_method_call(AstNode* node, Scope* scope, ErrorList* errors,
snprintf(mangled, sizeof(mangled), "%s$%s", recv_struct,
node->as.method_call.method_name);
Symbol* sym = scope_lookup(scope, mangled);
// trait 方法 fallback: 搜索所有作用域中以 $method_name 结尾的符号
// trait 方法 fallback: 搜索所有作用域中以 $method_name 结尾且以 StructName 开头的符号
if (!sym || sym->kind != SYM_FUNCTION) {
char suffix[256];
snprintf(suffix, sizeof(suffix), "$%s", node->as.method_call.method_name);
size_t suf_len = strlen(suffix);
size_t recv_len = strlen(recv_struct);
for (const Scope* sc = scope; sc; sc = sc->parent) {
for (Symbol* s = sc->head; s; s = s->next) {
if (s->kind == SYM_FUNCTION) {
size_t name_len = strlen(s->name);
if (name_len > suf_len && strcmp(s->name + name_len - suf_len, suffix) == 0) {
if (name_len > suf_len + recv_len
&& strncmp(s->name, recv_struct, recv_len) == 0
&& strcmp(s->name + name_len - suf_len, suffix) == 0) {
sym = s;
// 更新 method_name 为找到的完整函数名(codegen 需要)
node->as.method_call.method_name = s->name;
break;
}
}
@@ -578,6 +579,10 @@ static void analyze_method_call(AstNode* node, Scope* scope, ErrorList* errors,
if (sym) break;
}
}
// 更新 method_name 为符号的实际名称(codegen 需要通过它找到 LLVM 函数)
if (sym && sym->kind == SYM_FUNCTION) {
node->as.method_call.method_name = sym->name;
}
if (!sym || sym->kind != SYM_FUNCTION) {
error_add(errors, "<sema>", node->loc.line, node->loc.col,
"结构体 '%s' 没有方法 '%s'", recv_struct,
@@ -700,6 +705,21 @@ static void analyze_node(AstNode* node, Scope* scope, ErrorList* errors, Arena*
}
for (size_t j = 0; j < impl->as.impl_block.method_count; j++) {
AstNode* method = impl->as.impl_block.methods[j];
// Self → 实际结构体名(参数类型)
for (size_t k = 0; k < method->as.function.param_count; k++) {
AstNode* p = method->as.function.params[k];
if (p->as.parameter.type == TYPE_STRUCT
&& p->as.parameter.struct_type_name
&& strcmp(p->as.parameter.struct_type_name, "Self") == 0) {
p->as.parameter.struct_type_name = st_name;
}
}
// Self → 实际结构体名(返回类型)
if (method->as.function.return_type == TYPE_STRUCT
&& method->as.function.return_struct_type_name
&& strcmp(method->as.function.return_struct_type_name, "Self") == 0) {
method->as.function.return_struct_type_name = st_name;
}
// 构造改名后的函数名
char mangled[256];
snprintf(mangled, sizeof(mangled), "%s$%s", st_name,