Files
TermiNexus f52fc90221 test(lifetime): 字段逃逸负例从 main 移入普通函数
入口 main 已整体豁免栈逃逸检查(其帧生命期=进程生命期),逃逸写在 main 里会被放行、负向用例失效。改为 CaseField()/CaseAnnField() 承载逃逸、main 调用,保持 P3 规则仍被覆盖。
2026-10-10 14:47:04 +08:00

38 lines
1.8 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from stdint import *
# =============================================================================
# 负向工程(**应当编译失败**):P3 —— 注解赋值的**属性目标**同样受"长命左值"约束
#
# §12-P3 的实例:`obj.f: T = <短命右值>`。与普通赋值 `obj.f = <短命右值>` 是**同一条规则**,
# 只是语法形态是 AnnAssign(带类型注解)。此前 translate_annassign 对非 Name 目标直接 return 0,
# 整条语句被**静默丢弃**(既不报错也不写出)——本工程同时守住"不静默"与"P3 必须拦截"两点。
#
# 判据(见 AssignGenMixin._translate_lvalue_annassign):
# · 左值 h.p 的存储属于**堆对象**(h 由 `new heap hlife` 得到)→ 活得比本帧长;
# · 右值 &local 是**本帧栈地址**(LIFE_FRAME)→ 出帧即成悬垂指针。
# 期望报错:LifetimeError。
#
# 对照(必须放行):`local_struct.f: int* = &local2`(左值也在本帧,FRAME)→ 两者同命,合法;
# `h.p: int* = heap_ptr`(右值生命期不短于左值)→ 合法。
# 注意 h 必须在**同一个函数**里 `new`,否则它作为形参进来时 Life=UNKNOWN(保守放行)。
# =============================================================================
novirtual class Holder:
p: int*
# 逃逸必须写在**非 main** 函数里:入口 main 现在整体豁免栈逃逸检查
# (其帧生命期 = 进程生命期),写在 main 里会被放行、负向用例失效。
def CaseAnnField() -> int:
h: Holder* = new heap hlife Holder()
local: int = 7
h.p: int* = &local # ← 必须被拒:注解形态的属性赋值把本帧栈地址写进堆对象字段
return 0
export def main() -> int:
CaseAnnField()
return 0