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:
+24
-4
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user