fix(func): 末尾收尾的可达性判据只认 _ctrl_merge_reachable(删掉“穷尽通配臂即不可达”的错误推断)
症状:includes/llvmlite/__types.vp::_TypePrintDepth 末句 match ty:(各臂只 snprintf 后 br 到 merge)被生成 match.end: unreachable;llc 不给可达 unreachable 生成任何指令 ⇒ 执行掉进布局紧随其后的同一 switch 跳转表,用上一条 snprintf 的返回值 3 当 tag 取 table[3]=Array 臂 ⇒ 把 Int 的 Bits(32) 当指针递归解引用 ⇒ AV at 0x20(裸 0xC0000005;ASan 下同一崩溃被转为 0x80000003 = -2147483645) 根因:last_is_ctrl and (_ctrl_merge_reachable == 0 or MatchHasWildcardArm(...)) 的“追加92”通配臂子句——穷尽性只保证匹配总能命中某臂,不保证各臂都终止且不 br 到 merge;而 _ctrl_merge_reachable 恰是逐臂真正 br end_bb 时才置 1 的精确信号(MatchGenMixin:717 写回) 修法:两处收尾判据(FuncGenDef 模块级函数 / ClassGenVTable 方法)都只在 _ctrl_merge_reachable == 0 时 build_unreachable;merge 可达时走既有分支正常收尾(void→ret void;无注解→ConstZero;有非 void 注解→fail-fast,不发明返回值) 删除随之失效的 MatchHasWildcardArm 与其私有 helper _IsWildcardPattern(全仓已无引用)
This commit is contained in:
1 parent
5e100e2195
commit
f2d7b748ea
3 files changed
+20
-76
No files matched your search
@@ -989,14 +989,12 @@ novirtual class ClassGenVTable(ClassGenBase.ClassGenBase):
|
||||
_is_void = 1
|
||||
if _is_void != 0:
|
||||
llvmlite.build_ret_void(func_builder)
|
||||
elif last_is_ctrl != 0 and (trans._ctrl_merge_reachable == 0 \
|
||||
or self.Gen.MatchGen.MatchHasWildcardArm(last_stmt3_m) != 0):
|
||||
# 非 void 方法末句是控制流且 merge 块结构性不可达(全分支 return,无 br
|
||||
elif last_is_ctrl != 0 and trans._ctrl_merge_reachable == 0:
|
||||
# 非 void 方法末句是控制流且 merge 块**结构性**不可达(全分支 return,无 br
|
||||
# 到 merge)→ LLVM 语义 unreachable。merge 可达时须正常收尾(下方
|
||||
# ConstZero / fail-fast),否则 llc O2 把 br-to-unreachable 优化为
|
||||
# fall-through → 双分支执行崩溃。
|
||||
# 追加92:末句 match 含无 guard 的 `case _:` 穷尽通配臂时同样不可达
|
||||
# (同 FuncGenDef 模块级函数口径)。
|
||||
# ConstZero / fail-fast):可达块的 unreachable 是 UB,llc 不生成指令 ⇒
|
||||
# 执行掉进布局紧随其后的块(同 FuncGenDef 模块级函数口径;实测反例见该处
|
||||
# 注释里的 _TypePrintDepth 用 snprintf 返回值当 tag 走进 switch 跳转表)。
|
||||
llvmlite.build_unreachable(func_builder)
|
||||
elif fd.returns is None:
|
||||
# 无返回类型注解 → 无返回值过程方法,默认零值返回
|
||||
|
||||
Reference in new issue
Block a user