fix(gen): define 复用前置声明时按源码形参名对齐签名参数名,修签名与函数体两套参数名导致 MLIR「region entry argument already in use」
This commit is contained in:
1 parent
bc1eeb6e38
commit
12da1cbfc1
1 file changed
+27
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user