From 879134fe3cff73be57c6dab35a3b19b3f4308b38 Mon Sep 17 00:00:00 2001 From: nyash-codex Date: Sat, 22 Nov 2025 08:52:46 +0900 Subject: [PATCH] =?UTF-8?q?fix(phi):=20do=5Floop=5Fexit=20=E3=81=A7unreach?= =?UTF-8?q?able=E3=83=96=E3=83=AD=E3=83=83=E3=82=AF=E4=BD=9C=E6=88=90?= =?UTF-8?q?=E3=82=92=E5=BB=83=E6=AD=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **問題**: - break/continue後に `switch_to_unreachable_block_with_void()` 呼び出し - 新しいunreachableブロック作成 → PHI生成に悪影響 - domination error: `Value %48 used in block bb55 but defined in non-dominating block bb53` **修正内容**: - 3. Void定数定義(戻り値用ダミー) - 4. ジャンプ命令発行 - 5. 新しいunreachableブロックは作らない(`Ok(void_id)` 直接返却) **効果**: - 余分なブロック(bb53等)が作られない - PHI生成の前提条件が正しく保たれる - LoopForm v2 + ControlForm 設計に完全準拠 **実装者**: ChatGPT先生 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/mir/loop_builder.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/mir/loop_builder.rs b/src/mir/loop_builder.rs index 43ca5316..3d131e10 100644 --- a/src/mir/loop_builder.rs +++ b/src/mir/loop_builder.rs @@ -102,8 +102,9 @@ impl<'a> LoopBuilder<'a> { /// # 処理フロー /// 1. 現在の変数マップをスナップショット /// 2. [LoopForm] スナップショット保存(Break → exit_snapshots, Continue → continue_snapshots) - /// 3. [LoopForm] ターゲットブロックへジャンプ(Break → exit, Continue → header/continue_merge) - /// 4. unreachable ブロックに切り替え + /// 3. Void を定義(戻り値用のダミー) + /// 4. [LoopForm] ターゲットブロックへジャンプ(Break → exit, Continue → header/continue_merge) + /// 5. 現在ブロックはジャンプで終端済みのまま維持(新しい unreachable ブロックは作らない) fn do_loop_exit(&mut self, kind: LoopExitKind) -> Result { // 1. スナップショット取得(共通処理) let snapshot = self.get_current_variable_map(); @@ -128,7 +129,11 @@ impl<'a> LoopBuilder<'a> { } } - // 3. ターゲットブロックへジャンプ(kind別処理) + // 3. 戻り値用のダミーを定義(現在ブロック内で完結させる) + let void_id = self.new_value(); + self.emit_const(void_id, ConstValue::Void)?; + + // 4. ターゲットブロックへジャンプ(kind別処理) match kind { LoopExitKind::Break => { if let Some(exit_bb) = crate::mir::builder::loops::current_exit(self.parent_builder) @@ -145,8 +150,8 @@ impl<'a> LoopBuilder<'a> { } } - // 4. unreachable ブロックに切り替え(共通処理) - self.switch_to_unreachable_block_with_void() + // 5. 現在ブロックは jump で終端済み。新しい unreachable ブロックは作らない。 + Ok(void_id) } /// Handle a `break` statement: jump to loop exit and continue in a fresh unreachable block.