fix(narrow): StructGenMixin 守卫候选与归纳区间常量改用 int64,消除 64->32 隐式窄化

kv/lo/hi/k 原本声明为 int 承接 int64(Scratch[...]),触发新禁止的隐式窄化;_AddGuardCand/_PackEscapeClear 的 kv 形参同步拓宽为 int64(打包范围检查需看到完整 64 位值),打包结果处显式 int() 收窄
This commit is contained in:
TermiNexus committed 2026-10-10 22:20:47 +08:00
1 parent 41772b4a0c
commit d023e9932d
1 file changed
+8 -8
+8 -8
View File
@@ -1302,7 +1302,7 @@ novirtual class StructGenMixin:
self.EscConstEnv = prev_e
return ok
def _AddGuardCand(self, out: sizet*, n: int, max: int, p: int, kv: int) -> int:
def _AddGuardCand(self, out: sizet*, n: int, max: int, p: int, kv: int64) -> int:
"""加一条守卫候选并按 (形参位, 常量) 去重;返回新条数"""
if out is None or n >= max: return n
i: int = 0
@@ -1328,7 +1328,7 @@ novirtual class StructGenMixin:
return n
p: int = -1
add_false: int = 0
kv: int = 1
kv: int64 = 1
if k == ast.ASTKind.Name:
p = self._ParamIndex(fd, node)
add_false = 1
@@ -1382,12 +1382,12 @@ novirtual class StructGenMixin:
n = self._CollectGuardCandidates(fd, whn.orelse, out, max, depth + 1)
return n
def _PackEscapeClear(self, p: int, kv: int, m: int) -> int:
def _PackEscapeClear(self, p: int, kv: int64, m: int) -> int:
"""打包 (守卫形参位, 常量, 被清掉的掩码) 成一个整数;超出打包范围返回 -1(只影响精度)"""
if p < 0 or p > 255: return -1
if kv < EC_PACK_K_MIN or kv > EC_PACK_K_MAX: return -1
if m <= 0: return -1
return p + (kv & 255) * 256 + m * 65536
return int(p + (kv & 255) * 256 + m * 65536)
def compute_escape_clears(self, pool: memhub.MemBuddy*, fd: ast.FunctionDef*, out_packed: sizet*, max: int) -> int:
"""算出可落 .vpi 的"常量守卫"记录条数(0=没有)。每条 = 打包的 (守卫形参位, 常量, 被清掉的位掩码)。
@@ -1409,7 +1409,7 @@ novirtual class StructGenMixin:
ci: int = 0
while ci < ncand and n_out < max:
p: int = int(cand[ci * 2])
kv: int = int64(cand[ci * 2 + 1])
kv: int64 = int64(cand[ci * 2 + 1])
ci += 1
if p < 0 or p >= EC_ENV_MAX: continue
string.memset(env, 0, sizet(EC_ENV_MAX) * 2 * 8)
@@ -1520,11 +1520,11 @@ novirtual class StructGenMixin:
"""`<归纳变量> <op> <常量>` 按区间判定:1=恒真 / 0=恒假 / -1=判不定"""
if self._IndRangeOf(a_side) == 0: return -1
# 先拷出区间,再做常量侧求值(求值会用到 EC_EVAL_SLOT,且其递归理论上有机会覆写区间槽)
lo: int = int64(self.EscRefineScratch[EC_IND_LO])
hi: int = int64(self.EscRefineScratch[EC_IND_HI])
lo: int64 = int64(self.EscRefineScratch[EC_IND_LO])
hi: int64 = int64(self.EscRefineScratch[EC_IND_HI])
# 常量侧用当前环境求值(`i == n` 里的 n 也可能被调用点常量绑定)
if self._EvalConstInt(fd, b_side, 0) == 0: return -1
k: int = int64(self.EscRefineScratch[EC_EVAL_SLOT])
k: int64 = int64(self.EscRefineScratch[EC_EVAL_SLOT])
if op == ast.OpKind.Eq:
if lo == k and hi == k: return 1
if k < lo or k > hi: return 0