fix(tpc): 带注解重声明冲突不再静默丢 store,改为 fail-fast 报错
原有变量分支整段包在 try/except Exception 里,隐式窄化抛出的 FailFastError 被吞成一条 strict 警告 ⇒ alloca 已建、store 整条丢失 ⇒ 之后 load 读到未初始化栈槽(运行期随机崩溃,且无任何编译期提示)。现场:ViperC 由 TPC 引导时 Converter.vp 'di: sizet = ai - (an - dn)'(di 已由 for 循环绑定为 int/i32)→ 生成的 viperc.exe 在 list[AST*].get 处 ASan 越界读(READ 0x1296f00c1808)。现改为捕获后重抛带变量名/两侧类型的清晰错误。
This commit is contained in:
1 parent
5f1d2c3300
commit
b51faef1cb
1 file changed
+27
-16
@@ -891,23 +891,34 @@ class AnnAssignHandle(BaseHandle):
|
||||
Gen._record_var_signedness(VarName, IsUnsigned)
|
||||
return
|
||||
if InitValue:
|
||||
try:
|
||||
VarPtr: ir.Value = Gen.variables[VarName]
|
||||
if isinstance(VarPtr.type, ir.PointerType):
|
||||
TargetType: ir.Type = VarPtr.type.pointee
|
||||
if InitValue.type != TargetType:
|
||||
# 统一走 `_coerce_value`(隐式转换的唯一收敛点):
|
||||
# 此前这里手写 `zext/trunc`,整型加宽一律 zext ⇒ 负常量被当无符号
|
||||
# 处理(现场:`b: int64 = -196608` 落成 0x00000000FFFD0000 大正数,
|
||||
# IntWidthTest Test 5/6 的 FAIL)。`_coerce_value` 对 i32→i64 用
|
||||
# `sext` 保持符号,隐式窄化亦按规则 fail-fast。
|
||||
# 【不再静默兜底】此前整段包在 `try/except Exception` 里,转换/落址失败
|
||||
# 只记一条 strict 警告就继续 ⇒ alloca 已建、store 被跳过 ⇒ 之后 load 读到
|
||||
# 未初始化栈槽(运行期随机崩溃)。现场:ViperC 由 TPC 引导时
|
||||
# Converter.vp `di: sizet = ai - (an - dn)` 与 for 循环变量 `di`(int/i32)
|
||||
# 冲突 → store 整条丢失 → 生成的 viperc.exe 在 list[AST*].get 处
|
||||
# ASan 越界读(READ 0x1296f00c1808)。
|
||||
VarPtr: ir.Value = Gen.variables[VarName]
|
||||
if isinstance(VarPtr.type, ir.PointerType):
|
||||
TargetType: ir.Type = VarPtr.type.pointee
|
||||
if InitValue.type != TargetType:
|
||||
# 统一走 `_coerce_value`(隐式转换的唯一收敛点):
|
||||
# 此前这里手写 `zext/trunc`,整型加宽一律 zext ⇒ 负常量被当无符号
|
||||
# 处理(现场:`b: int64 = -196608` 落成 0x00000000FFFD0000 大正数,
|
||||
# IntWidthTest Test 5/6 的 FAIL)。`_coerce_value` 对 i32→i64 用
|
||||
# `sext` 保持符号,隐式窄化亦按规则 fail-fast。
|
||||
from lib.core.LLVMCG.FuncGen import FailFastError
|
||||
try:
|
||||
_coerced: ir.Value | None = Gen._coerce_value(InitValue, TargetType, Node)
|
||||
if _coerced is not None:
|
||||
InitValue = _coerced
|
||||
Gen._store(InitValue, VarPtr)
|
||||
except Exception as _e:
|
||||
if _config_mode == "strict":
|
||||
self.Trans.LogWarning(f"异常被忽略: {_e}")
|
||||
except FailFastError as _cce:
|
||||
raise FailFastError(
|
||||
f"带注解重声明冲突:变量 '{VarName}' 已有存储类型 {TargetType}"
|
||||
f"(来自前面的声明或循环变量),此处注解声明的右值类型为 "
|
||||
f"{InitValue.type},无法收窄进既有存储;请改用另一个变量名,"
|
||||
f"或让既有声明与注解类型一致。原始错误:{_cce}"
|
||||
) from None
|
||||
if _coerced is not None:
|
||||
InitValue = _coerced
|
||||
Gen._store(InitValue, VarPtr)
|
||||
Gen._record_var_signedness(VarName, IsUnsigned)
|
||||
return
|
||||
if VarName in Gen.global_vars:
|
||||
|
||||
Reference in new issue
Block a user