From a45b806afa28c70b6aff524c1472ffe721fa5be2 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 19 Aug 2026 01:04:42 +0800 Subject: [PATCH] =?UTF-8?q?fix(match):=20merge=20=E5=8F=AF=E8=BE=BE?= =?UTF-8?q?=E6=80=A7=E7=94=A8=E5=B1=80=E9=83=A8=E6=A0=87=E5=BF=97=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=EF=BC=8C=E6=B6=88=E9=99=A4=20case=20=E4=BD=93?= =?UTF-8?q?=E5=86=85=E5=B5=8C=E5=A5=97=20if=20=E6=B1=A1=E6=9F=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 主 match/sequence/simple 三条路径:case 体内嵌套 If(无 else + return)翻译时把 _ctrl_merge_reachable 置 1,全 case return 的 match 被误判 merge 可达 → 函数收尾 fail-fast '流程掉出末尾'(LLvmLiteTest includes/llvmlite/__module.vp _is_opaque_struct)。改用局部变量记录本 match 自身的 br end_bb,收尾覆盖全局标志 --- App/lib/core/Handles/HandlesMatch.vp | 29 +++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/App/lib/core/Handles/HandlesMatch.vp b/App/lib/core/Handles/HandlesMatch.vp index 96abab4..76282b6 100644 --- a/App/lib/core/Handles/HandlesMatch.vp +++ b/App/lib/core/Handles/HandlesMatch.vp @@ -80,8 +80,14 @@ class MatchHandle(HandlesBase.Mixin): if builder is None or func is None: return 0 - # 追加90:match merge 可达性重置(下方 br end_bb 处置 1) + # 追加90:match merge 可达性重置(下方 br end_bb 处置 1)。 + # 嵌套语句(case 体内的 If/While 等)翻译时会改写 _ctrl_merge_reachable, + # 用局部变量单独记录"本 match 是否有 br 进入 end_bb",收尾时覆盖, + # 消除嵌套控制流污染(_is_opaque_struct 的 case 内 if 无 else + return + # 把标志置 1,全 case return 的 match 被误判 merge 可达 → 函数收尾 + # fail-fast "流程掉出末尾",见 LLvmLiteTest/__module.vp)。 trans._ctrl_merge_reachable = 0 + m_merge_reach: int = 0 m_node: ast.Match | t.CPtr = (ast.Match | t.CPtr)(node) @@ -513,6 +519,7 @@ class MatchHandle(HandlesBase.Mixin): and nb == 0: llvmlite.build_br(builder, end_bb) trans._ctrl_merge_reachable = 1 + m_merge_reach = 1 i = i + 1 @@ -523,6 +530,7 @@ class MatchHandle(HandlesBase.Mixin): if llvmlite.builder_cur_block_is_terminated(builder) == 0: llvmlite.build_br(builder, end_bb) trans._ctrl_merge_reachable = 1 + m_merge_reach = 1 else: # 有显式 default:翻译 default case body(找到 is_def==1 的 case) di: int = 0 @@ -548,9 +556,13 @@ class MatchHandle(HandlesBase.Mixin): if llvmlite.builder_cur_block_is_terminated(builder) == 0: llvmlite.build_br(builder, end_bb) trans._ctrl_merge_reachable = 1 + m_merge_reach = 1 # 9. 定位到 end 块 llvmlite.position_at_end(builder, end_bb) + # 用本 match 自身的 br 记录覆盖,消除 case 体内嵌套控制流对 + # _ctrl_merge_reachable 的污染(全 case return 时应为不可达) + trans._ctrl_merge_reachable = m_merge_reach return 0 # ============================================================ @@ -721,6 +733,9 @@ class MatchHandle(HandlesBase.Mixin): func: llvmlite.Function | t.CPtr = trans._cur_func if builder is None or func is None: return 0 + # 同主路径:局部记录本 sequence match 的 br end_bb,收尾覆盖 + # _ctrl_merge_reachable,消除 case 体内嵌套控制流污染 + sq_merge_reach: int = 0 # 1. 求值 subject 各元素 elts: list[ast.AST | t.CPtr] | t.CPtr = None @@ -987,6 +1002,7 @@ class MatchHandle(HandlesBase.Mixin): else: llvmlite.build_br(builder, end_bb) trans._ctrl_merge_reachable = 1 + sq_merge_reach = 1 ci = ci + 1 # 7. default 块 @@ -1014,9 +1030,12 @@ class MatchHandle(HandlesBase.Mixin): di = di + 1 if llvmlite.builder_cur_block_is_terminated(builder) == 0: llvmlite.build_br(builder, end_bb) + sq_merge_reach = 1 # 8. 定位到 end llvmlite.position_at_end(builder, end_bb) + # 覆盖嵌套控制流污染(同主路径) + trans._ctrl_merge_reachable = sq_merge_reach return 0 # ============================================================ @@ -1030,6 +1049,9 @@ class MatchHandle(HandlesBase.Mixin): pool: memhub.MemBuddy | t.CPtr = trans.Pool builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder func: llvmlite.Function | t.CPtr = trans._cur_func + # 同主路径:局部记录本 simple match 的 br end_bb,收尾覆盖 + # _ctrl_merge_reachable,消除 case 体内嵌套控制流污染 + sm_merge_reach: int = 0 # 1. subject 转 i32(若已 i32 直接用,否则 ptrtoint) i32_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool) @@ -1205,6 +1227,7 @@ class MatchHandle(HandlesBase.Mixin): and nb == 0: llvmlite.build_br(builder, end_bb) trans._ctrl_merge_reachable = 1 + sm_merge_reach = 1 i = i + 1 @@ -1214,6 +1237,7 @@ class MatchHandle(HandlesBase.Mixin): if llvmlite.builder_cur_block_is_terminated(builder) == 0: llvmlite.build_br(builder, end_bb) trans._ctrl_merge_reachable = 1 + sm_merge_reach = 1 else: di: int = 0 while di < collected: @@ -1238,9 +1262,12 @@ class MatchHandle(HandlesBase.Mixin): if llvmlite.builder_cur_block_is_terminated(builder) == 0: llvmlite.build_br(builder, end_bb) trans._ctrl_merge_reachable = 1 + sm_merge_reach = 1 # 8. 定位到 end llvmlite.position_at_end(builder, end_bb) + # 覆盖嵌套控制流污染(同主路径) + trans._ctrl_merge_reachable = sm_merge_reach return 0