From 953c829e9f503f919351573620c946b5e3019c71 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Fri, 9 Oct 2026 22:40:30 +0800 Subject: [PATCH] =?UTF-8?q?feat(lifetime):=20=E6=9E=84=E9=80=A0=E5=99=A8?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E5=A1=AB=20recv=5Flife=E2=80=94=E2=80=94?= =?UTF-8?q?=E8=A3=B8=20T()=20=E6=9E=84=E9=80=A0=EF=BC=88=E5=85=A5=E5=8F=A3?= =?UTF-8?q?=E5=9D=97=20alloca=EF=BC=89=E7=AE=97=20FRAME?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _translate_struct_ctor 两份副本都算 recv_life_ct:_g_new_storage == None(无 new 描述符提供存储)→ 裸 T() 的存储是入口块 alloca → LIFE_FRAME(参与构造器同命裁剪);非空(存储来自 new …)→ -1 不裁剪。 两处 __init__ 调用点(:171 / :675)均传入。覆盖 CtorHolder(&l) / BoxCtor(&l) 这类裸构造误报。 --- App/lib/core/Gen/Call/CallGenCtor.vp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/App/lib/core/Gen/Call/CallGenCtor.vp b/App/lib/core/Gen/Call/CallGenCtor.vp index 5be0152..073722f 100644 --- a/App/lib/core/Gen/Call/CallGenCtor.vp +++ b/App/lib/core/Gen/Call/CallGenCtor.vp @@ -82,6 +82,11 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): tmp: mlirlite.Value* = _g_new_storage if tmp is None: tmp = self.Gen.VarGen._alloca_at_entry(builder, struct_ty) if tmp is None: return mlirlite.ConstZero(pool, struct_ty) + # 构造器同命裁剪用:被构造对象的生命期。 + # 裸 `T()`(没有 `new` 描述符提供存储)= 入口块 alloca → **FRAME**; + # 存储来自 `new …`(_g_new_storage 非空)时来源/生命期由**上游**决定,这里不猜 → -1(不裁剪)。 + recv_life_ct: int = -1 + if _g_new_storage is None: recv_life_ct = GenTypes.LIFE_FRAME # Diagnostic node: the first ctor arg (has a line number) so _call_method_on_ptr's # fatal_error can show the call line (this function has no cl param). diag_node_ct: ast.AST* = None @@ -168,7 +173,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): arg_vals[real_arg_count] = sizet(av) real_arg_count += 1 - self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, class_name, "__init__", storage_ptr, arg_vals, real_arg_count, trans, diag_node_ct, is_volatile, cargs) + self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, class_name, "__init__", storage_ptr, arg_vals, real_arg_count, trans, diag_node_ct, is_volatile, cargs, recv_life_ct) elif has_new_flag == 0: # No __init__ and no __new__: store args field by field # (with __new__, args were already consumed and must not be stored). @@ -548,6 +553,11 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): tmp: mlirlite.Value* = _g_new_storage if tmp is None: tmp = self.Gen.VarGen._alloca_at_entry(builder, struct_ty) if tmp is None: return mlirlite.ConstZero(pool, struct_ty) + # 构造器同命裁剪用:被构造对象的生命期。 + # 裸 `T()`(没有 `new` 描述符提供存储)= 入口块 alloca → **FRAME**; + # 存储来自 `new …`(_g_new_storage 非空)时来源/生命期由**上游**决定,这里不猜 → -1(不裁剪)。 + recv_life_ct: int = -1 + if _g_new_storage is None: recv_life_ct = GenTypes.LIFE_FRAME # Diagnostic node: the first ctor arg (has a line number) so _call_method_on_ptr's # fatal_error can show the call line (this function has no cl param). diag_node_ct: ast.AST* = None @@ -662,7 +672,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase): init_arg_count += 1 # call __init__(storage_ptr, *args) - self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, class_name, "__init__", storage_ptr, init_arg_vals, init_arg_count, trans, diag_node_ct, is_volatile, cargs) + self.Gen.CallGenCall._call_method_on_ptr(pool, builder, mod, class_name, "__init__", storage_ptr, init_arg_vals, init_arg_count, trans, diag_node_ct, is_volatile, cargs, recv_life_ct) # return the pointer return storage_ptr