From e1b05fe1c6f0b128f8750472f0f7f7882491db9a Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Mon, 17 Aug 2026 18:43:39 +0800 Subject: [PATCH] =?UTF-8?q?fix(gen):=20If=20=E5=88=86=E6=94=AF=E5=B5=8C?= =?UTF-8?q?=E5=A5=97=E6=8E=A7=E5=88=B6=E6=B5=81=E5=85=A8=20return=20?= =?UTF-8?q?=E8=A1=A5=20unreachable=EF=BC=8C=E4=BF=AE=E5=A4=8D=20atan2=20?= =?UTF-8?q?=E8=AF=AF=E5=88=A4=E6=B5=81=E7=A8=8B=E6=8E=89=E5=87=BA=E6=9C=AB?= =?UTF-8?q?=E5=B0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 嵌套 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,保持结构性不可达语义 --- App/lib/core/Handles/HandlesIf.vp | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/App/lib/core/Handles/HandlesIf.vp b/App/lib/core/Handles/HandlesIf.vp index e260795..6128387 100644 --- a/App/lib/core/Handles/HandlesIf.vp +++ b/App/lib/core/Handles/HandlesIf.vp @@ -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 时任一分支