fix(core): 末句控制流 merge 可达性存 trans 字段(追加90)
控制流翻译器(If/While/For/Match)记录 merge 可达性到 trans._ctrl_merge_reachable; FuncGenMixin/ClassGenMixin 仅在全分支 return(结构性不可达)时生成 unreachable, 可达则正常收尾(ConstZero/fail-fast)。修复 llc O2 优化 br-to-unreachable 为 fall-through 导致 check 类函数 PASS+FAIL 双分支执行 + int3 崩溃(FuncTest)。
This commit is contained in:
1 parent
f4a990c074
commit
996f08fb46
7 files changed
+58
-8
No files matched your search
@@ -4533,9 +4533,13 @@ class ClassGenMixin:
|
||||
pass
|
||||
if _is_void != 0:
|
||||
llvmlite.build_ret_void(func_builder)
|
||||
elif last_is_ctrl != 0:
|
||||
# 非 void 方法末句是控制流且块未 terminated:merge 块
|
||||
# 结构性不可达(不可能抵达),LLVM 语义 unreachable
|
||||
elif last_is_ctrl != 0 and trans._ctrl_merge_reachable == 0:
|
||||
# 追加90(与 FuncGenMixin 同步):非 void 方法末句是控制流
|
||||
# 且 merge 块结构性不可达(全分支 return,无 br 到 merge)
|
||||
# → LLVM 语义 unreachable。merge 可达(分支 br 到 merge)时
|
||||
# 不是结构性不可达,需正常收尾(下方 ConstZero / fail-fast)。
|
||||
# 原无条件 unreachable 使 llc O2 优化 br-to-unreachable 为
|
||||
# fall-through → 双分支执行崩溃(FuncTest check)
|
||||
llvmlite.build_unreachable(func_builder)
|
||||
elif fd.returns is None:
|
||||
# 无返回类型注解 → 无返回值过程方法,默认零值返回
|
||||
|
||||
@@ -1137,9 +1137,14 @@ class FuncGenMixin:
|
||||
pass
|
||||
if _is_void != 0:
|
||||
llvmlite.build_ret_void(func_builder)
|
||||
elif last_is_ctrl != 0:
|
||||
# 非 void 函数末句是控制流且块未 terminated:merge 块
|
||||
# 结构性不可达(不可能抵达),LLVM 语义 unreachable
|
||||
elif last_is_ctrl != 0 and trans._ctrl_merge_reachable == 0:
|
||||
# 追加90:非 void 函数末句是控制流且 merge 块结构性不可达
|
||||
# (全分支 return,无 br 到 merge)→ LLVM 语义 unreachable。
|
||||
# 注意:merge 可达(分支 br 到 merge,如 testcheck.check 的
|
||||
# if/else 无 return)时不是结构性不可达,需正常收尾(下方
|
||||
# ConstZero / fail-fast)。原实现无条件 unreachable 使 llc
|
||||
# O2 把 br-to-unreachable 优化为 fall-through → 双分支执行
|
||||
# 崩溃(FuncTest check PASS+FAIL 双打印)
|
||||
llvmlite.build_unreachable(func_builder)
|
||||
elif fd.returns is None:
|
||||
# 无返回类型注解 → 无返回值过程函数,默认零值返回
|
||||
|
||||
@@ -418,6 +418,8 @@ class ForHandle(HandlesBase.Mixin):
|
||||
|
||||
# 11. 定位到 end 块
|
||||
llvmlite.position_at_end(builder, end_bb)
|
||||
# 追加90:for 循环正常结束路径 br 到 end_bb → merge 恒可达(需正常收尾)
|
||||
trans._ctrl_merge_reachable = 1
|
||||
return new_vars
|
||||
|
||||
# ============================================================
|
||||
@@ -564,6 +566,8 @@ class ForHandle(HandlesBase.Mixin):
|
||||
|
||||
# 定位到 end 块
|
||||
llvmlite.position_at_end(builder, end_bb)
|
||||
# 追加90:for 循环正常结束路径 br 到 end_bb → merge 恒可达(需正常收尾)
|
||||
trans._ctrl_merge_reachable = 1
|
||||
return new_vars
|
||||
|
||||
# ============================================================
|
||||
@@ -696,6 +700,8 @@ class ForHandle(HandlesBase.Mixin):
|
||||
|
||||
# 定位到 end 块
|
||||
llvmlite.position_at_end(builder, end_bb)
|
||||
# 追加90:for 循环正常结束路径 br 到 end_bb → merge 恒可达(需正常收尾)
|
||||
trans._ctrl_merge_reachable = 1
|
||||
return new_vars
|
||||
|
||||
# ============================================================
|
||||
@@ -891,6 +897,8 @@ class ForHandle(HandlesBase.Mixin):
|
||||
|
||||
# 定位到 end 块
|
||||
llvmlite.position_at_end(builder, end_bb)
|
||||
# 追加90:for 循环正常结束路径 br 到 end_bb → merge 恒可达(需正常收尾)
|
||||
trans._ctrl_merge_reachable = 1
|
||||
return new_vars
|
||||
|
||||
def _handle_dict_iter(self, for_node: ast.For | t.CPtr,
|
||||
@@ -1000,6 +1008,8 @@ class ForHandle(HandlesBase.Mixin):
|
||||
|
||||
# 定位到 end 块
|
||||
llvmlite.position_at_end(builder, end_bb)
|
||||
# 追加90:for 循环正常结束路径 br 到 end_bb → merge 恒可达(需正常收尾)
|
||||
trans._ctrl_merge_reachable = 1
|
||||
return new_vars
|
||||
|
||||
# ============================================================
|
||||
@@ -1183,6 +1193,8 @@ class ForHandle(HandlesBase.Mixin):
|
||||
llvmlite.position_at_end(builder, step_bb)
|
||||
llvmlite.build_br(builder, cond_bb)
|
||||
llvmlite.position_at_end(builder, end_bb)
|
||||
# 追加90:for 循环正常结束路径 br 到 end_bb → merge 恒可达(需正常收尾)
|
||||
trans._ctrl_merge_reachable = 1
|
||||
return new_vars
|
||||
|
||||
# ============================================================
|
||||
@@ -1570,6 +1582,8 @@ class ForHandle(HandlesBase.Mixin):
|
||||
|
||||
# 定位到 end 块
|
||||
llvmlite.position_at_end(builder, end_bb)
|
||||
# 追加90:for 循环正常结束路径 br 到 end_bb → merge 恒可达(需正常收尾)
|
||||
trans._ctrl_merge_reachable = 1
|
||||
return new_vars
|
||||
|
||||
|
||||
|
||||
@@ -299,11 +299,14 @@ class IfHandle(HandlesBase.Mixin):
|
||||
if stmt is not None:
|
||||
HandlesBody.translate_stmt(trans, stmt)
|
||||
|
||||
# then 块未终止则跳到 merge
|
||||
# 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
|
||||
|
||||
# 6. 翻译 else body(若有)
|
||||
else_branches_merge: int = 0
|
||||
if has_else == 1:
|
||||
llvmlite.position_at_end(builder, else_bb)
|
||||
else_count: t.CSizeT = len(orelse_list)
|
||||
@@ -313,8 +316,17 @@ class IfHandle(HandlesBase.Mixin):
|
||||
HandlesBody.translate_stmt(trans, stmt)
|
||||
if llvmlite.builder_cur_block_is_terminated(builder) == 0:
|
||||
llvmlite.build_br(builder, merge_bb)
|
||||
else_branches_merge = 1
|
||||
|
||||
# 7. 定位到 merge 块继续后续代码
|
||||
# 7. merge 块可达性(追加90,末句控制流收尾判定用):
|
||||
# 无 else 时 cond_br 直接跳 merge(恒可达);有 else 时任一分支
|
||||
# br 到 merge 即可达;全分支 return(无 br)才结构性不可达。
|
||||
# 经 HandlesBase 模块级全局传递(避免依赖 Translator 字段表)
|
||||
trans._ctrl_merge_reachable = 1
|
||||
if has_else == 1 and then_branches_merge == 0 and else_branches_merge == 0:
|
||||
trans._ctrl_merge_reachable = 0
|
||||
|
||||
# 8. 定位到 merge 块继续后续代码
|
||||
llvmlite.position_at_end(builder, merge_bb)
|
||||
return 0
|
||||
|
||||
|
||||
@@ -80,6 +80,9 @@ class MatchHandle(HandlesBase.Mixin):
|
||||
if builder is None or func is None:
|
||||
return 0
|
||||
|
||||
# 追加90:match merge 可达性重置(下方 br end_bb 处置 1)
|
||||
trans._ctrl_merge_reachable = 0
|
||||
|
||||
m_node: ast.Match | t.CPtr = (ast.Match | t.CPtr)(node)
|
||||
|
||||
# 1. 求值 subject
|
||||
@@ -509,6 +512,7 @@ class MatchHandle(HandlesBase.Mixin):
|
||||
if llvmlite.builder_cur_block_is_terminated(builder) == 0 \
|
||||
and nb == 0:
|
||||
llvmlite.build_br(builder, end_bb)
|
||||
trans._ctrl_merge_reachable = 1
|
||||
|
||||
i = i + 1
|
||||
|
||||
@@ -518,6 +522,7 @@ class MatchHandle(HandlesBase.Mixin):
|
||||
# 无显式 default:default 直接跳 end
|
||||
if llvmlite.builder_cur_block_is_terminated(builder) == 0:
|
||||
llvmlite.build_br(builder, end_bb)
|
||||
trans._ctrl_merge_reachable = 1
|
||||
else:
|
||||
# 有显式 default:翻译 default case body(找到 is_def==1 的 case)
|
||||
di: int = 0
|
||||
@@ -542,6 +547,7 @@ class MatchHandle(HandlesBase.Mixin):
|
||||
di = di + 1
|
||||
if llvmlite.builder_cur_block_is_terminated(builder) == 0:
|
||||
llvmlite.build_br(builder, end_bb)
|
||||
trans._ctrl_merge_reachable = 1
|
||||
|
||||
# 9. 定位到 end 块
|
||||
llvmlite.position_at_end(builder, end_bb)
|
||||
@@ -980,6 +986,7 @@ class MatchHandle(HandlesBase.Mixin):
|
||||
llvmlite.build_br(builder, default_bb)
|
||||
else:
|
||||
llvmlite.build_br(builder, end_bb)
|
||||
trans._ctrl_merge_reachable = 1
|
||||
ci = ci + 1
|
||||
|
||||
# 7. default 块
|
||||
@@ -1197,6 +1204,7 @@ class MatchHandle(HandlesBase.Mixin):
|
||||
if llvmlite.builder_cur_block_is_terminated(builder) == 0 \
|
||||
and nb == 0:
|
||||
llvmlite.build_br(builder, end_bb)
|
||||
trans._ctrl_merge_reachable = 1
|
||||
|
||||
i = i + 1
|
||||
|
||||
@@ -1205,6 +1213,7 @@ class MatchHandle(HandlesBase.Mixin):
|
||||
if has_default == 0:
|
||||
if llvmlite.builder_cur_block_is_terminated(builder) == 0:
|
||||
llvmlite.build_br(builder, end_bb)
|
||||
trans._ctrl_merge_reachable = 1
|
||||
else:
|
||||
di: int = 0
|
||||
while di < collected:
|
||||
@@ -1228,6 +1237,7 @@ class MatchHandle(HandlesBase.Mixin):
|
||||
di = di + 1
|
||||
if llvmlite.builder_cur_block_is_terminated(builder) == 0:
|
||||
llvmlite.build_br(builder, end_bb)
|
||||
trans._ctrl_merge_reachable = 1
|
||||
|
||||
# 8. 定位到 end
|
||||
llvmlite.position_at_end(builder, end_bb)
|
||||
|
||||
@@ -109,6 +109,9 @@ class Translator:
|
||||
# 独立标签计数器(不与 builder.Counter 共享,避免 SSA 编号非单调)
|
||||
_label_counter: t.CInt
|
||||
|
||||
# 追加90:控制流 merge 块可达性(1=有 br 进入可达/0=全分支 return 结构性不可达)
|
||||
_ctrl_merge_reachable: t.CInt
|
||||
|
||||
# global 声明的变量名集合(当前函数内)
|
||||
_global_names: str
|
||||
_global_name_count: t.CInt
|
||||
|
||||
@@ -141,6 +141,8 @@ class WhileHandle(HandlesBase.Mixin):
|
||||
|
||||
# 5. 定位到 end 块
|
||||
llvmlite.position_at_end(builder, end_bb)
|
||||
# 追加90:while 的 cond_br 恒引用 end_bb → merge 恒可达(需正常收尾)
|
||||
trans._ctrl_merge_reachable = 1
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user