fix(gen): define 复用前置声明时按源码形参名对齐签名参数名,修签名与函数体两套参数名导致 MLIR「region entry argument already in use」

This commit is contained in:
TermiNexus committed 2026-10-13 20:33:06 +08:00
1 parent bc1eeb6e38
commit 12da1cbfc1
1 file changed
+27
+27
View File
@@ -462,6 +462,33 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase):
if func is not None and mlirlite.function_is_declared(func) != 0:
# Reuse the forward declare: clear IsDeclared and turn it into a define
func.IsDeclared = 0
# 参数名对齐(根因修复):复用的前置声明未必是 forward_declare_functions 按源码建的,也可能是
# **模块前言**里 Translator 建的 C 库声明(如 free 用合成名 "p")。而函数体是用**源码形参名**
# %<arg.arg> 生成参数 SSA 引用的(见下方 alloca 段的 SSAValue)。若签名沿用声明里的旧名,就会
# 打印出 `llvm.func @f(%p) { ... %ptr ... }`:入口实参是 %p,体内 %ptr 却在 f 内未定义,
# mlir-opt 会把 %ptr 解析到后续同名函数的入口实参并报 "region entry argument '%ptr' is already
# in use"(现场:VKernel 的 free 头 %p / 体 %ptr,被解析到 _slab_find_page(%ptr))。
# 故这里按源码形参名重写复用到的形参名,使签名与函数体一致。forward_declare_functions 建的前置
# 声明本就用源码名,此处对其幂等(同名重写)。
reused_p: mlirlite.Param* = mlirlite.function_get_param_head(func)
if args_node is not None:
reuse_ags: ast.Arguments* = ast.Arguments*(args_node)
if reuse_ags.args is not None:
reuse_list: list[ast.AST*]* = reuse_ags.args
reuse_n: sizet = len(reuse_list)
for reuse_i in range(int(reuse_n)):
rearg: ast.Arg* = ast.Arg*(reuse_list.get(reuse_i))
if rearg is None or rearg.arg is None: continue
# CVoid means empty param: not part of the signature (mirrors the add_param loops above)
if rearg.annotation is not None and self.Gen.TypeGenResolve._is_t_attr(rearg.annotation, "CVoid", imported_modules) != 0: continue
if reused_p is None:
# 复用声明形参少于定义:签名与函数体必然错配,禁止静默,fail-fast
self.Gen.TypeGenErr.fatal_error(rearg, f"reused declaration for '{fd.name}' has fewer parameters than the definition", "TypeError")
return 0
reuse_pname: str = pool.alloc(32)
if reuse_pname is not None: viperlib.snprintf(reuse_pname, 32, "%%%s", rearg.arg)
reused_p.Name = reuse_pname
reused_p = mlirlite.param_get_next(reused_p)
# Set decorator attributes (not set when the forward declare was created)
func_attrs_reuse: str = self.Gen.FuncGenBase.extract_func_attrs(pool, fd.decorator_list, imported_modules)
if func_attrs_reuse is not None: mlirlite.function_set_attrs(func, func_attrs_reuse)