fix(mir): PHI検証panic修正 - update_cfg()を検証前に呼び出し
A案実装: debug_verify_phi_inputs呼び出し前にCFG predecessorを更新
修正箇所(7箇所):
- src/mir/builder/phi.rs:50, 73, 132, 143
- src/mir/builder/ops.rs:273, 328, 351
根本原因:
- Branch/Jump命令でsuccessorは即座に更新
- predecessorはupdate_cfg()で遅延再構築
- PHI検証が先に実行されてpredecessor未更新でpanic
解決策:
- 各debug_verify_phi_inputs呼び出し前に
if let Some(func) = self.current_function.as_mut() {
func.update_cfg();
}
を挿入してCFGを同期
影響: if/else文、論理演算子(&&/||)のPHI生成が正常動作
This commit is contained in:
@ -13,13 +13,13 @@ static box ParserExprBox {
|
||||
local at = pair.lastIndexOf("@")
|
||||
local json = pair.substring(0, at)
|
||||
local pos = i
|
||||
if at >= 0 { pos = ctx.to_int(pair.substring(at+1, pair.size())) }
|
||||
if at >= 0 { pos = ctx.to_int(pair.substring(at+1, pair.length())) }
|
||||
ctx.gpos_set(pos)
|
||||
return json
|
||||
}
|
||||
|
||||
parse_string2(src, i, ctx) {
|
||||
local n = src.size()
|
||||
local n = src.length()
|
||||
local j = i + 1
|
||||
local out = ""
|
||||
local guard = 0
|
||||
@ -57,7 +57,7 @@ static box ParserExprBox {
|
||||
|
||||
parse_factor2(src, i, ctx) {
|
||||
local j = ctx.skip_ws(src, i)
|
||||
if j >= src.size() {
|
||||
if j >= src.length() {
|
||||
ctx.gpos_set(j)
|
||||
return "{\"type\":\"Int\",\"value\":0}"
|
||||
}
|
||||
@ -116,13 +116,13 @@ static box ParserExprBox {
|
||||
local idp = ctx.read_ident2(src, p)
|
||||
local at = idp.lastIndexOf("@")
|
||||
local cls = idp.substring(0, at)
|
||||
local k = ctx.to_int(idp.substring(at+1, idp.size()))
|
||||
local k = ctx.to_int(idp.substring(at+1, idp.length()))
|
||||
k = ctx.skip_ws(src, k)
|
||||
if src.substring(k, k+1) == "(" { k = k + 1 }
|
||||
local args_and_pos = me.parse_args2(src, k, ctx)
|
||||
local at2 = args_and_pos.lastIndexOf("@")
|
||||
local args_json = args_and_pos.substring(0, at2)
|
||||
k = ctx.to_int(args_and_pos.substring(at2+1, args_and_pos.size()))
|
||||
k = ctx.to_int(args_and_pos.substring(at2+1, args_and_pos.length()))
|
||||
k = ctx.skip_ws(src, k)
|
||||
if src.substring(k, k+1) == ")" { k = k + 1 }
|
||||
ctx.gpos_set(k)
|
||||
@ -134,7 +134,7 @@ static box ParserExprBox {
|
||||
local idp = ctx.read_ident2(src, j)
|
||||
local at = idp.lastIndexOf("@")
|
||||
local name = idp.substring(0, at)
|
||||
local k = ctx.to_int(idp.substring(at+1, idp.size()))
|
||||
local k = ctx.to_int(idp.substring(at+1, idp.length()))
|
||||
local node = "{\"type\":\"Var\",\"name\":\"" + name + "\"}"
|
||||
local cont2 = 1
|
||||
|
||||
@ -147,7 +147,7 @@ static box ParserExprBox {
|
||||
local args_and_pos = me.parse_args2(src, k, ctx)
|
||||
local at2 = args_and_pos.lastIndexOf("@")
|
||||
local args_json = args_and_pos.substring(0, at2)
|
||||
k = ctx.to_int(args_and_pos.substring(at2+1, args_and_pos.size()))
|
||||
k = ctx.to_int(args_and_pos.substring(at2+1, args_and_pos.length()))
|
||||
k = ctx.skip_ws(src, k)
|
||||
if src.substring(k, k+1) == ")" { k = k + 1 }
|
||||
node = "{\"type\":\"Call\",\"name\":\"" + name + "\",\"args\":" + args_json + "}"
|
||||
@ -158,13 +158,13 @@ static box ParserExprBox {
|
||||
local midp = ctx.read_ident2(src, k)
|
||||
local at3 = midp.lastIndexOf("@")
|
||||
local mname = midp.substring(0, at3)
|
||||
k = ctx.to_int(midp.substring(at3+1, midp.size()))
|
||||
k = ctx.to_int(midp.substring(at3+1, midp.length()))
|
||||
k = ctx.skip_ws(src, k)
|
||||
if src.substring(k, k+1) == "(" { k = k + 1 }
|
||||
local args2 = me.parse_args2(src, k, ctx)
|
||||
local at4 = args2.lastIndexOf("@")
|
||||
local args_json2 = args2.substring(0, at4)
|
||||
k = ctx.to_int(args2.substring(at4+1, args2.size()))
|
||||
k = ctx.to_int(args2.substring(at4+1, args2.length()))
|
||||
k = ctx.skip_ws(src, k)
|
||||
if src.substring(k, k+1) == ")" { k = k + 1 }
|
||||
node = "{\"type\":\"Method\",\"recv\":" + node + ",\"method\":\"" + mname + "\",\"args\":" + args_json2 + "}"
|
||||
@ -201,7 +201,7 @@ static box ParserExprBox {
|
||||
|
||||
loop(cont == 1) {
|
||||
j = ctx.skip_ws(src, j)
|
||||
if j >= src.size() {
|
||||
if j >= src.length() {
|
||||
cont = 0
|
||||
} else {
|
||||
local op = src.substring(j, j+1)
|
||||
@ -226,7 +226,7 @@ static box ParserExprBox {
|
||||
|
||||
loop(cont == 1) {
|
||||
j = ctx.skip_ws(src, j)
|
||||
if j >= src.size() {
|
||||
if j >= src.length() {
|
||||
cont = 0
|
||||
} else {
|
||||
local op = src.substring(j, j+1)
|
||||
@ -301,7 +301,7 @@ static box ParserExprBox {
|
||||
j = ctx.skip_ws(src, j)
|
||||
local else_expr = me.parse_expr2(src, j, ctx)
|
||||
j = ctx.gpos_get()
|
||||
if else_expr.size() == 0 { else_expr = "{\"type\":\"Int\",\"value\":0}" }
|
||||
if else_expr.length() == 0 { else_expr = "{\"type\":\"Int\",\"value\":0}" }
|
||||
ctx.gpos_set(j)
|
||||
return "{\"type\":\"Ternary\",\"cond\":" + lhs + ",\"then\":" + then_expr + ",\"else\":" + else_expr + "}"
|
||||
}
|
||||
@ -312,7 +312,7 @@ static box ParserExprBox {
|
||||
|
||||
parse_args2(src, i, ctx) {
|
||||
local j = ctx.skip_ws(src, i)
|
||||
local n = src.size()
|
||||
local n = src.length()
|
||||
local out = "["
|
||||
j = ctx.skip_ws(src, j)
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
static box ParserLiteralBox {
|
||||
// Map literal: {"k": v, ...} (string keys only) → Call{name:"map.of", args:[Str(k1), v1, Str(k2), v2, ...]}
|
||||
parse_map(src, i, ctx) {
|
||||
local n = src.size()
|
||||
local n = src.length()
|
||||
local j = i + 1 // skip opening '{'
|
||||
local out = "["
|
||||
local first = 1
|
||||
@ -68,7 +68,7 @@ static box ParserLiteralBox {
|
||||
|
||||
// Array literal: [e1, e2, ...] → Call{name:"array.of", args:[...]}
|
||||
parse_array(src, i, ctx) {
|
||||
local n = src.size()
|
||||
local n = src.length()
|
||||
local j = i + 1 // skip opening '['
|
||||
local out = "["
|
||||
local first = 1
|
||||
|
||||
@ -7,7 +7,7 @@ static box ParserPeekBox {
|
||||
parse(src, i, ctx) {
|
||||
// ctx is ParserBox for delegation
|
||||
local j = i
|
||||
local n = src.size()
|
||||
local n = src.length()
|
||||
|
||||
// Parse scrutinee expression
|
||||
local scr = ctx.parse_expr2(src, j)
|
||||
|
||||
Reference in New Issue
Block a user