feat(gen): 调用点逃逸检查(M2.3 v1b 步骤4)

translate_call 里按被调者摘要核对实参:第 k 位为 1(该形参会逃逸/被返回)的形参位上,实参若交出本帧栈地址(&local / 局部数组退让)即报 LifetimeError。此处拿不到被调者形参类型,故传哑指针类型,仅用于让 life_of_expr 判定裸局部数组名处于指针位置=退让。
This commit is contained in:
TermiNexus committed 2026-10-08 13:41:00 +08:00
1 parent 4ce577d8fb
commit 52fd89decf
1 file changed
+11
+11
View File
@@ -74,6 +74,17 @@ novirtual class CallGenMixin(CallGenBase.CallGenBase):
cargs: list[ast.AST*]* = cl.args
can: sizet = 0
if cargs is not None: can = len(cargs)
# 调用点生命期检查(M2.3 v1b 步骤4):被调者"会逃逸或直接返回"的形参位上,实参不得
# 交出本帧栈地址(&local / 局部数组退让)。此处拿不到被调者形参类型,故传一个哑指针
# 类型——只用于让 life_of_expr 判定"裸局部数组名处于指针位置 = 数组退让 = 栈地址"。
if cargs is not None and func_name is not None:
esc_mask: int = GenApi.get_param_escapes(func_name)
if esc_mask != 0:
_dummy_ptr: mlirlite.LLVMType* = mlirlite.Ptr(pool, mlirlite.Int8(pool))
for ai in range(can):
if ((esc_mask >> int(ai)) & 1) != 0:
GenApi.fail_if_stack_addr_escape(cargs.get(ai), "an argument bound to a parameter that the callee escapes or returns", trans, _dummy_ptr)
# Generic function calls (PEP 695 def f[T]) are intercepted first: infer type args and
# monomorphize here (templates emit no plain function); hit_box=1 means handled-with-void.
h0_hit: t.CPtr = stdlib.malloc(4)