diff --git a/lib/core/Handles/HandlesExprCall.py b/lib/core/Handles/HandlesExprCall.py index fa5a5a3..3ef2fa3 100644 --- a/lib/core/Handles/HandlesExprCall.py +++ b/lib/core/Handles/HandlesExprCall.py @@ -2473,14 +2473,13 @@ class ExprCallHandle(BaseHandle): if ArgVal.type == TargetType: return ArgVal if isinstance(TargetType, ir.IntType) and isinstance(ArgVal.type, ir.IntType): - # 统一走 `_coerce_value`(隐式/显式转换的唯一收敛点):此前手写 `zext`, - # 整型加宽一律零扩展 ⇒ 负值被当无符号(现场:`int64(-1)` 里 -1 的 i32 位型 - # 变成 4294967295 ⇒ `x ^ int64(-1)` 变号 ⇒ IntWidthTest Test 5 第三条 - # 循环不收敛)。`_coerce_value` 加宽用 `sext` 保符号,窄化按其规则 fail-fast。 - _coerced_td: ir.Value | None = Gen._coerce_value(ArgVal, TargetType, Node) - if _coerced_td is not None: - return _coerced_td - return ArgVal + if ArgVal.type.width < TargetType.width: + # **显式**强转的加宽必须保符号:此前手写 zext,负值/负数常量会被零扩展 + # (现场:`int64(-1)` 变 4294967295;IntWidthTest Test 5)。 + return Gen.builder.sext(ArgVal, TargetType, name=f"sext_{TypedefName}_cast") + elif ArgVal.type.width > TargetType.width: + # 显式窄化 = 截断(“隐式窄化禁止”只针对**隐式**路径,不拦显式转换) + return Gen.builder.trunc(ArgVal, TargetType, name=f"trunc_{TypedefName}_cast") if isinstance(TargetType, ir.PointerType): if isinstance(ArgVal.type, ir.PointerType): return Gen.builder.bitcast(ArgVal, TargetType, name=f"bitcast_{TypedefName}_cast") @@ -2541,13 +2540,13 @@ class ExprCallHandle(BaseHandle): if ArgVal.type == TargetType: return ArgVal if isinstance(TargetType, ir.IntType) and isinstance(ArgVal.type, ir.IntType): - # 统一走 `_coerce_value`(隐式/显式转换的唯一收敛点):此前手写 `zext`, - # 整型加宽一律零扩展 ⇒ 负值被当无符号。 - # 现场:`int64(-1)` → i64 4294967295 ⇒ `x ^ int64(-1)` 变号、循环不收敛 - # (IntWidthTest Test 5 第三条);`_coerce_value` 加宽用 `sext` 保符号。 - _coerced_b: ir.Value | None = Gen._coerce_value(ArgVal, TargetType, Node) - if _coerced_b is not None: - return _coerced_b + # builtins typedef 数值转换(int64(bool) / uint64(i32) 等):加宽保符号(sext), + # 窄化=截断(显式转换不受“隐式窄化禁止”约束)。 + # 此前加宽用 zext,`int64(-1)` 会变成 4294967295(IntWidthTest Test 5)。 + if ArgVal.type.width < TargetType.width: + return Gen.builder.sext(ArgVal, TargetType, name="sext_typedef_cast") + elif ArgVal.type.width > TargetType.width: + return Gen.builder.trunc(ArgVal, TargetType, name="trunc_typedef_cast") return ArgVal if isinstance(TargetType, ir.PointerType): if isinstance(ArgVal.type, ir.PointerType):