From 12da1cbfc12924372162c799aff35cc8511cfb28 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Tue, 13 Oct 2026 20:33:06 +0800 Subject: [PATCH] =?UTF-8?q?fix(gen):=20define=20=E5=A4=8D=E7=94=A8?= =?UTF-8?q?=E5=89=8D=E7=BD=AE=E5=A3=B0=E6=98=8E=E6=97=B6=E6=8C=89=E6=BA=90?= =?UTF-8?q?=E7=A0=81=E5=BD=A2=E5=8F=82=E5=90=8D=E5=AF=B9=E9=BD=90=E7=AD=BE?= =?UTF-8?q?=E5=90=8D=E5=8F=82=E6=95=B0=E5=90=8D=EF=BC=8C=E4=BF=AE=E7=AD=BE?= =?UTF-8?q?=E5=90=8D=E4=B8=8E=E5=87=BD=E6=95=B0=E4=BD=93=E4=B8=A4=E5=A5=97?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E5=90=8D=E5=AF=BC=E8=87=B4=20MLIR=E3=80=8Cre?= =?UTF-8?q?gion=20entry=20argument=20already=20in=20use=E3=80=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App/lib/core/Gen/Func/FuncGenDef.vp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/App/lib/core/Gen/Func/FuncGenDef.vp b/App/lib/core/Gen/Func/FuncGenDef.vp index 0a7b230..58c1b6c 100644 --- a/App/lib/core/Gen/Func/FuncGenDef.vp +++ b/App/lib/core/Gen/Func/FuncGenDef.vp @@ -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")。而函数体是用**源码形参名** + # % 生成参数 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)