From 6b86f846ca4f945b395139a0abbd530e8b6c9bf3 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Thu, 15 Oct 2026 21:40:30 +0800 Subject: [PATCH] =?UTF-8?q?fix(lifetime):=20=E5=80=BC=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E5=B1=80=E9=83=A8=E5=8F=98=E9=87=8F=E5=9C=A8=E5=90=8C=E5=9E=8B?= =?UTF-8?q?=E8=81=9A=E5=90=88=E7=9B=AE=E6=A0=87=E4=BD=8D=E7=BD=AE=E6=8C=89?= =?UTF-8?q?=E5=80=BC=E6=8B=B7=E8=B4=9D(LIFE=5FVALUE)=20-=20=E4=BF=AE=20ret?= =?UTF-8?q?urn=20col=20=E8=A2=AB=E8=AF=AF=E5=88=A4=20stack=20address=20esc?= =?UTF-8?q?apes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App/lib/core/Gen/AssignGenMixin.vp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/App/lib/core/Gen/AssignGenMixin.vp b/App/lib/core/Gen/AssignGenMixin.vp index a081f37..9c3397c 100644 --- a/App/lib/core/Gen/AssignGenMixin.vp +++ b/App/lib/core/Gen/AssignGenMixin.vp @@ -1041,6 +1041,16 @@ novirtual class AssignGenMixin: # 本帧局部数组名:退让到指针目标交出栈地址;同型聚合目标是值拷贝 if target_ty is not None and self.Gen.ExprGenBase.is_ptr_type(target_ty) != 0: return GenTypes.LIFE_FRAME return GenTypes.LIFE_VALUE + # 值类型(聚合)局部变量的存储是入口块 alloca(符号表登记的是 alloca 指针,见 + # VarGenMixin.lookup_var),但**目标位置是同型聚合值**时语义是值拷贝:交出的是整块 + # 拷贝,与源帧无关 ⇒ LIFE_VALUE。与下方 Call 分支的裸构造 `T(...)` 同口径。 + # 此前只对「裸数组名(inner 是 Array)」给了这条口径,于是 `col: V3 = V3(...)` 后 + # `return col` 落到 get_var_life 读回本帧 LIFE_FRAME,被 check_return_frame_decl 误拦 + # (LifetimeError: stack address escapes)。 + if (inner is not None and target_ty is not None + and self.Gen.ExprGenBase.is_ptr_type(target_ty) == 0 + and self._stg_ty_equal(trans.Pool, inner, target_ty) != 0): + return GenTypes.LIFE_VALUE # 指针/标量变量:读登记的生命期(默认 UNKNOWN) return self.Gen.VarGen.get_var_life(trans.SymTab, nm.id) if k == ast.ASTKind.UnaryOp: