feat(hako_check): Phase 154 MIR CFG integration & HC020 dead block detection

Implements block-level unreachable code detection using MIR CFG information.
Complements Phase 153's method-level HC019 with fine-grained analysis.

Core Infrastructure (Complete):
- CFG Extractor: Extract block reachability from MirModule
- DeadBlockAnalyzerBox: HC020 rule for unreachable blocks
- CLI Integration: --dead-blocks flag and rule execution
- Test Cases: 4 comprehensive patterns (early return, constant false, infinite loop, break)
- Smoke Test: Validation script for all test cases

Implementation Details:
- src/mir/cfg_extractor.rs: New module for CFG→JSON extraction
- tools/hako_check/rules/rule_dead_blocks.hako: HC020 analyzer box
- tools/hako_check/cli.hako: Added --dead-blocks flag and HC020 integration
- apps/tests/hako_check/test_dead_blocks_*.hako: 4 test cases

Architecture:
- Follows Phase 153 boxed modular pattern (DeadCodeAnalyzerBox)
- Optional CFG field in Analysis IR (backward compatible)
- Uses MIR's built-in reachability computation
- Gracefully skips if CFG unavailable

Known Limitation:
- CFG data bridge pending (Phase 155): analysis_consumer.hako needs MIR access
- Current: DeadBlockAnalyzerBox implemented, but CFG not yet in Analysis IR
- Estimated 2-3 hours to complete bridge in Phase 155

Test Coverage:
- Unit tests: cfg_extractor (simple CFG, unreachable blocks)
- Integration tests: 4 test cases ready (will activate with bridge)
- Smoke test: tools/hako_check_deadblocks_smoke.sh

Documentation:
- phase154_mir_cfg_inventory.md: CFG structure investigation
- phase154_implementation_summary.md: Complete implementation guide
- hako_check_design.md: HC020 rule documentation

Next Phase 155:
- Implement CFG data bridge (extract_mir_cfg builtin)
- Update analysis_consumer.hako to call bridge
- Activate HC020 end-to-end testing

🤖 Generated with Claude Code (https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-04 15:00:45 +09:00
parent 11221aec29
commit 000335c32e
16 changed files with 1535 additions and 4 deletions

View File

@ -329,3 +329,55 @@ $ ./target/release/hakorune --backend vm test.hako
**Note**: JoinIR 経路はプレースホルダー実装のため、実際にはレガシー経路で処理。
環境変数読み取りとフラグ分岐は完全に動作しており、Phase 124 で JoinIR 実装を追加すれば即座に動作可能。
## HC020: Unreachable Basic Block (Phase 154)
**Rule ID:** HC020
**Severity:** Warning
**Category:** Dead Code (Block-level)
### Description
Detects unreachable basic blocks using MIR CFG information. Complements HC019 by providing fine-grained analysis at the block level rather than method level.
### Patterns Detected
1. **Early return**: Code after unconditional return
2. **Constant conditions**: Branches that can never be taken (`if 0`, `if false`)
3. **Infinite loops**: Code after `loop(1)`
4. **Unconditional break**: Code after break statement
### Usage
```bash
# Enable HC020 alone
./tools/hako_check.sh --dead-blocks program.hako
# Combined with HC019
./tools/hako_check.sh --dead-code --dead-blocks program.hako
# Via rules filter
./tools/hako_check.sh --rules dead_blocks program.hako
```
### Example Output
```
[HC020] Unreachable basic block: fn=Main.test bb=5 (after early return) :: test.hako:10
[HC020] Unreachable basic block: fn=Foo.bar bb=12 (dead conditional) :: test.hako:25
```
### Requirements
- Requires MIR CFG information (Phase 154+)
- Gracefully skips if CFG unavailable
- Works with NYASH_JOINIR_STRICT=1 mode
### Implementation
- **Analyzer:** `tools/hako_check/rules/rule_dead_blocks.hako`
- **CFG Extractor:** `src/mir/cfg_extractor.rs`
- **Tests:** `apps/tests/hako_check/test_dead_blocks_*.hako`