From 52fd89decf8c88fac432c1d1ad21d067917aa6e0 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Thu, 8 Oct 2026 13:41:00 +0800 Subject: [PATCH] =?UTF-8?q?feat(gen):=20=E8=B0=83=E7=94=A8=E7=82=B9?= =?UTF-8?q?=E9=80=83=E9=80=B8=E6=A3=80=E6=9F=A5=EF=BC=88M2.3=20v1b=20?= =?UTF-8?q?=E6=AD=A5=E9=AA=A44=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit translate_call 里按被调者摘要核对实参:第 k 位为 1(该形参会逃逸/被返回)的形参位上,实参若交出本帧栈地址(&local / 局部数组退让)即报 LifetimeError。此处拿不到被调者形参类型,故传哑指针类型,仅用于让 life_of_expr 判定裸局部数组名处于指针位置=退让。 --- App/lib/core/Gen/Call/CallGenMixin.vp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/App/lib/core/Gen/Call/CallGenMixin.vp b/App/lib/core/Gen/Call/CallGenMixin.vp index e18faa6..83179a4 100644 --- a/App/lib/core/Gen/Call/CallGenMixin.vp +++ b/App/lib/core/Gen/Call/CallGenMixin.vp @@ -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)