fix(viperc/life): 进程入口豁免补上 _start(ViperOS 应用入口),消除栈逃逸误报

现象:Apps/HelloWorld/main.vp 报 LifetimeError(`master` frame-local,传给构造器参数会
悬垂)。而 `master = &root` 中 root 是 _start 的帧内 Tk,_start 是进程入口
(@__attribute__(section(".text.startup")),结尾 mainloop/process.exit),本帧返回即进程
结束 —— 与 main 同口径,确无逃逸。

_CurFuncIsEntryMain 此前只认 "main",现把 `_start` 一并视为进程入口。
This commit is contained in:
TermiNexus committed 2026-10-14 15:53:28 +08:00
1 parent a23c1bda3e
commit 6b180c8f59
1 file changed
+8 -3
+8 -3
View File
@@ -1055,14 +1055,19 @@ novirtual class AssignGenMixin:
self.Gen.VarGen.set_var_life(trans.SymTab, tnm.id, life)
return 0
# _CurFuncIsEntryMain - 当前正在翻译的函数是否为**入口 main**(1=是 / 0=否)。
# _CurFuncIsEntryMain - 当前正在翻译的函数是否为**进程入口**(1=是 / 0=否)。
# 进程入口有两类:`main`(普通可执行)与 `_start`(ViperOS 应用/库的导出入口,
# 见 `@__attribute__(section(".text.startup"), ...)`)。两者的帧生命期都等于进程生命期:
# 本帧返回即进程结束,栈对象其后不可能再被使用 —— 故同样不做栈地址逃逸检查。
# 嵌套函数不算:它们的帧不是进程生命期,不能享受豁免。
def _CurFuncIsEntryMain(self, trans: HT.Translator*) -> int:
"""当前函数是否为入口 main(按 llirlite 函数名判,与 FuncGenDef 对 main 不改名同口径)"""
"""当前函数是否为进程入口(main / _start;与 FuncGenDef 对入口不改名同口径)"""
if trans is None or trans._cur_func is None: return 0
nm: str = mlirlite.function_get_name(trans._cur_func)
if nm is None: return 0
return 1 if string.strcmp(nm, "main") == 0 else 0
if string.strcmp(nm, "main") == 0: return 1
if string.strcmp(nm, "_start") == 0: return 1
return 0
# fail_if_life_escapes - 汇点检查:被写出表达式的生命期为 LIFE_FRAME → LifetimeError。
# 这是 GenApi.fail_if_stack_addr_escape 的唯一实现(语法判据已并入 life_of_expr)。