fix(lifetime): 值类型变量按值拷贝判据改为双非指针(不再依赖类型打印比较),堆/静态登记优先
This commit is contained in:
1 parent
6b86f846ca
commit
5dc483e256
1 file changed
+15
-10
@@ -1035,24 +1035,29 @@ novirtual class AssignGenMixin:
|
||||
if GenApi.is_nonlocal_name(trans, nm.id) != 0: return GenTypes.LIFE_UNKNOWN
|
||||
v: mlirlite.Value* = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
if v is None: return GenTypes.LIFE_STATIC
|
||||
# 变量已登记为堆/静态生命期(如 `o: T* = new heap T()` 的指针变量):以登记为准,
|
||||
# 下面按"值类型"放宽只针对未登记的帧内局部变量,避免把堆/静态对象误放宽成值拷贝。
|
||||
rg: int = self.Gen.VarGen.get_var_life(trans.SymTab, nm.id)
|
||||
if rg == GenTypes.LIFE_HEAP or rg == GenTypes.LIFE_STATIC: return rg
|
||||
if v.Ty is not None and self.Gen.ExprGenBase.is_ptr_type(v.Ty) != 0:
|
||||
inner: mlirlite.LLVMType* = v.Ty.Pointee
|
||||
if inner is not None and inner.kind() == mlirlite.LLVMType.Array:
|
||||
# 本帧局部数组名:退让到指针目标交出栈地址;同型聚合目标是值拷贝
|
||||
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)。
|
||||
# 值类型(聚合/标量)局部变量:符号表登记的是入口块 alloca 指针(VarGenMixin.lookup_var),
|
||||
# 但读取这种变量就是**整块按值拷贝**,交出的是拷贝而非栈地址;当目标位置也是值类型
|
||||
# (函数按值返回、赋值给值类型槽)时判 LIFE_VALUE。与上方裸数组名、下方 Call 分支的
|
||||
# 裸构造 `T(...)` 同口径。
|
||||
# 此前只覆盖「裸数组名」,于是 `col: V3 = V3(...)` 后 `return col` 落到 get_var_life
|
||||
# 读回本帧 LIFE_FRAME,被 check_return_frame_decl 误报 LifetimeError。
|
||||
# 只排除"变量值本身或目标位置是地址"的情形:`p: V3*` 的 `return p` 仍判帧生命期。
|
||||
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):
|
||||
and self.Gen.ExprGenBase.is_ptr_type(inner) == 0
|
||||
and self.Gen.ExprGenBase.is_ptr_type(target_ty) == 0):
|
||||
return GenTypes.LIFE_VALUE
|
||||
# 指针/标量变量:读登记的生命期(默认 UNKNOWN)
|
||||
return self.Gen.VarGen.get_var_life(trans.SymTab, nm.id)
|
||||
# 指针变量/未定:读登记的生命期(默认 UNKNOWN)
|
||||
return rg
|
||||
if k == ast.ASTKind.UnaryOp:
|
||||
uo: ast.UnaryOp* = ast.UnaryOp*(node)
|
||||
if uo.op == ast.OpKind.AddrOf and uo.operand is not None and uo.operand.kind() == ast.ASTKind.Name:
|
||||
|
||||
Reference in new issue
Block a user