fix(gen): If 分支嵌套控制流全 return 补 unreachable,修复 atan2 误判流程掉出末尾

- 嵌套 If(全分支 return)翻译后 builder 停在嵌套 merge 块(无 terminator),外层 If 分支 terminated 判定误判为未终止 → 补 br merge → 顶层 _ctrl_merge_reachable 误置 1 → 函数末句 If 全 return 被判 merge 可达,fail-fast '流程掉出函数末尾'(vipermath.vp atan2 根因)
- 分支翻译前重置 _ctrl_merge_reachable=1 防残留值污染
- 分支末尾未 terminated 且 _ctrl_merge_reachable==0(嵌套控制流全 return)时补 build_unreachable 而非 br merge,保持结构性不可达语义
This commit is contained in:
TermiNexus committed 2026-08-17 18:43:39 +08:00
1 parent 33c8609882
commit e1b05fe1c6
1 file changed
+22 -4
+22 -4
View File
@@ -290,6 +290,10 @@ class IfHandle(HandlesBase.Mixin):
llvmlite.build_cond_br(builder, cond_i1, then_bb, merge_bb)
# 5. 翻译 then body
# 重置 merge 可达标志:分支内嵌套控制流会覆盖该标志,分支末尾判定依据
# "分支最后语句的控制流状态",须防进入本 If 前的残留值污染(append90
# 末句 If 全 return 被 fail-fast 误判"流程掉出末尾"的根因链一环)
trans._ctrl_merge_reachable = 1
llvmlite.position_at_end(builder, then_bb)
body: list[ast.AST | t.CPtr] | t.CPtr = if_node.children
if body is not None:
@@ -302,12 +306,22 @@ class IfHandle(HandlesBase.Mixin):
# then 块未终止则跳到 merge(记录 then 是否 br 到 merge)
then_branches_merge: int = 0
if llvmlite.builder_cur_block_is_terminated(builder) == 0:
llvmlite.build_br(builder, merge_bb)
then_branches_merge = 1
if trans._ctrl_merge_reachable == 0:
# 分支末尾是嵌套控制流且 merge 结构性不可达(全分支 return):
# 当前块是嵌套的 merge(无 terminator),补 unreachable 收尾。
# 不补 br merge——否则外层 If 的"分支是否 br merge"判定把不可达
# 分支当可达,函数末句 If 全 return 被误判"流程掉出末尾"
# (vipermath.vp atan2 根因;对齐 FuncGenDef append90 unreachable)
llvmlite.build_unreachable(builder)
else:
llvmlite.build_br(builder, merge_bb)
then_branches_merge = 1
# 6. 翻译 else body(若有)
else_branches_merge: int = 0
if has_else == 1:
# 同 then:重置标志防残留(else 是普通语句时不被 then 的嵌套控制流值污染)
trans._ctrl_merge_reachable = 1
llvmlite.position_at_end(builder, else_bb)
else_count: t.CSizeT = len(orelse_list)
for ei in range(else_count):
@@ -315,8 +329,12 @@ class IfHandle(HandlesBase.Mixin):
if stmt is not None:
HandlesBody.translate_stmt(trans, stmt)
if llvmlite.builder_cur_block_is_terminated(builder) == 0:
llvmlite.build_br(builder, merge_bb)
else_branches_merge = 1
if trans._ctrl_merge_reachable == 0:
# 嵌套控制流全分支 return:补 unreachable,不 br merge(同 then 分支)
llvmlite.build_unreachable(builder)
else:
llvmlite.build_br(builder, merge_bb)
else_branches_merge = 1
# 7. merge 块可达性(追加90,末句控制流收尾判定用):
# 无 else 时 cond_br 直接跳 merge(恒可达);有 else 时任一分支