fix(phi): do_loop_exit でunreachableブロック作成を廃止

**問題**:
- 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 <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-11-22 08:52:46 +09:00
parent fc16130d6b
commit 879134fe3c

View File

@ -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<ValueId, String> {
// 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.