feat(phi): Step 5-5-F/G - Prevent __pin$ from entering variable_map

Step 5-5-F: build_assignment() safeguard
- Skip inserting __pin$ temporaries into variable_map
- __pin$ variables are transient compiler-generated temps
- They should not persist across blocks or loops

Step 5-5-G: build_variable_access() safeguard
- Reject attempts to access __pin$ variables from variable_map
- Return clear error: "COMPILER BUG: Attempt to access __pin$ temporary"
- This catches stale __pin$ references early

Root Cause (Corrected):
- NOT BlockId renumbering (as Task initially thought)
- ChatGPT analysis: variable_map/snapshot/carrier have wrong ValueIds
- __pin$ temps were persisting and causing stale references

Test Status: 267 PASS / 1 FAIL (no regressions)

Next: Detailed MIR dump + VM trace analysis to find exact ValueId source

🐛 PHI Bug Option C実装: 箱分割設計で根本修正
This commit is contained in:
nyash-codex
2025-11-20 16:10:56 +09:00
parent 116c6cc74a
commit a98cc1b945

View File

@ -456,6 +456,17 @@ impl MirBuilder {
/// Build variable access /// Build variable access
pub(super) fn build_variable_access(&mut self, name: String) -> Result<ValueId, String> { pub(super) fn build_variable_access(&mut self, name: String) -> Result<ValueId, String> {
// Step 5-5-G: __pin$ variables should NEVER be accessed from variable_map
// They are transient temporaries created during expression building and
// should not persist across blocks. If we see one here, it's a compiler bug.
if name.starts_with("__pin$") {
return Err(format!(
"COMPILER BUG: Attempt to access __pin$ temporary '{}' from variable_map. \
__pin$ variables should only exist as direct SSA values, not as named variables.",
name
));
}
if let Some(&value_id) = self.variable_map.get(&name) { if let Some(&value_id) = self.variable_map.get(&name) {
Ok(value_id) Ok(value_id)
} else { } else {
@ -500,8 +511,18 @@ impl MirBuilder {
// SSA + PHI merges work correctly without explicit pinning here. // SSA + PHI merges work correctly without explicit pinning here.
// The expression building already creates necessary temporaries. // The expression building already creates necessary temporaries.
// In SSA form, each assignment creates a new value // Step 5-5-F: NEVER insert __pin$ temporaries into variable_map
self.variable_map.insert(var_name.clone(), value_id); // __pin$ variables are transient compiler-generated temporaries that should
// never be tracked as real variables. They are used only within expression
// building and should not persist across blocks or loops.
//
// BUG FIX: Previously, __pin$ variables would be inserted into variable_map,
// causing stale references after LoopForm transformation renumbers blocks.
// Result: VM would try to read undefined ValueIds (e.g., ValueId(270) at bb303).
if !var_name.starts_with("__pin$") {
// In SSA form, each assignment creates a new value
self.variable_map.insert(var_name.clone(), value_id);
}
Ok(value_id) Ok(value_id)
} }