fix(tpv): 类型静默退化改编译期报错 + 统一整数拓宽 zext/sext
- FuncGenDef: 有返回注解但解析失败 → fatal_error(不再静默回退 i32;无注解函数保留 i32 默认) - TypeGenResolve: 泛型类型实参污染(T→T 自映射 / 实参含类型参数名)→ fatal_error(不再 return None 静默退化) - ExprGenBase: coerce_to_type 窄→宽接入 _zext_or_sext_val(i1/i8 默认 zext、无符号类型名 zext、否则 sext),修正 t.CUInt32T 等无符号值被符号扩展的隐蔽数据损坏
This commit is contained in:
1 parent
24ae2dc966
commit
a8eb7fe5fe
11 files changed
+56
-56
No files matched your search
@@ -826,10 +826,7 @@ class AssignGenMixin:
|
||||
|
||||
if cur_val is None:
|
||||
# fail-fast: 目标变量当前值加载失败
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
target,
|
||||
f"无法加载目标变量 '{nm.id}' 的当前值",
|
||||
"TypeError")
|
||||
self.Gen.TypeGenErr.fatal_error(target, f"无法加载目标变量 '{nm.id}' 的当前值", "TypeError")
|
||||
|
||||
# 3. 翻译 RHS 值
|
||||
rhs_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
|
||||
@@ -8,11 +8,9 @@ import memhub
|
||||
import string
|
||||
import stdio
|
||||
import stdlib
|
||||
import sys
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.Stub.StubMerger.StubMergerCollect as StubMergerCollect
|
||||
|
||||
@@ -1,22 +1,14 @@
|
||||
import lib.core.Gen.GenTypes as GenTypes
|
||||
import t, c
|
||||
from stdint import *
|
||||
import ast
|
||||
import llvmlite
|
||||
import memhub
|
||||
import string
|
||||
import stdio
|
||||
import stdlib
|
||||
import sys
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
|
||||
import lib.core.Gen.Call.CallGenBase as CallGenBase
|
||||
import lib.core.Gen.GenApi as GenApi
|
||||
import lib.core.Gen.GenTypes as GenTypes
|
||||
from . import CallGenBase
|
||||
|
||||
|
||||
# ============================================================
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import lib.core.Gen.GenTypes as GenTypes
|
||||
import t, c
|
||||
from stdint import *
|
||||
import ast
|
||||
@@ -7,23 +6,14 @@ import memhub
|
||||
import string
|
||||
import stdio
|
||||
import stdlib
|
||||
import sys
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
|
||||
import lib.core.Gen.Call.CallGenBase as CallGenBase
|
||||
import lib.core.Gen.GenTypes as GenTypes
|
||||
from . import CallGenBase
|
||||
|
||||
|
||||
# ============================================================
|
||||
# CallGenCall - CallGenMixin 拆分(阶段 B):方法调用分派(含 super / 虚调用 / kwargs 名匹配)
|
||||
#
|
||||
# 继承 CallGenBase(1 级,TPV self 调用仅支持 1 级父类)。
|
||||
# 跨 Mixin 调用统一走 HandlesExprCall 委托(经 _g_gen)。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class CallGenCall(CallGenBase.CallGenBase):
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import lib.core.Gen.GenTypes as GenTypes
|
||||
import t, c
|
||||
from stdint import *
|
||||
import ast
|
||||
@@ -7,15 +6,12 @@ import memhub
|
||||
import string
|
||||
import stdio
|
||||
import stdlib
|
||||
import sys
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.core.Gen.GenTypes as GenTypes
|
||||
|
||||
import lib.core.Gen.Call.CallGenBase as CallGenBase
|
||||
from . import CallGenBase
|
||||
|
||||
|
||||
# ============================================================
|
||||
|
||||
@@ -17,8 +17,7 @@ import lib.core.VLogger as VLogger
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
|
||||
import lib.core.Gen.Call.CallGenBase as CallGenBase
|
||||
from . import CallGenBase
|
||||
import lib.core.Gen.GenApi as GenApi
|
||||
|
||||
|
||||
|
||||
@@ -415,9 +415,12 @@ class ExprGenBase:
|
||||
if val_bits == target_bits:
|
||||
return val
|
||||
if val_bits < target_bits:
|
||||
# i1 (bool) → 更宽整数用 zext(bool 语义:1 保持 1,而非 sext 的 0xFF...)
|
||||
# 与 HandlesReturn 中 return 语句的 i1 扩展规则保持一致
|
||||
if val_bits == 1:
|
||||
# 统一 zext/sext(问题2修正):i1/i8 默认 zext;AST 节点解析为
|
||||
# 无符号类型(t.CUIntXXT 强转/无符号类型名)走 zext;否则 sext。
|
||||
# 此前一律 sext(i1 除外)→ t.CUInt32T 等无符号值赋值/传参被符号
|
||||
# 扩展(高位置 1,如 0xFFFFFFFF 变 0xFFFFFFFFFFFFFFFF),与比较路径
|
||||
# should_zext_widen(i8 默认 zext)规则相反 → 隐蔽数据损坏。
|
||||
if self._zext_or_sext_val(pool, val, node) != 0:
|
||||
return llvmlite.build_zext(builder, val, target_ty)
|
||||
return llvmlite.build_sext(builder, val, target_ty)
|
||||
return llvmlite.build_trunc(builder, val, target_ty)
|
||||
@@ -450,6 +453,30 @@ class ExprGenBase:
|
||||
if self.is_ptr_type(val.Ty) != 0 and self.is_ptr_type(target_ty) != 0:
|
||||
return llvmlite.build_bitcast(builder, val, target_ty)
|
||||
return val
|
||||
|
||||
def _zext_or_sext_val(self, pool: memhub.MemBuddy | t.CPtr,
|
||||
val: llvmlite.Value | t.CPtr,
|
||||
node: ast.AST | t.CPtr = None) -> int:
|
||||
"""统一整数拓宽方向:1=zext(无符号语义),0=sext
|
||||
|
||||
规则(对齐 ExprGenOps.should_zext_widen / _node_type_unsigned):
|
||||
1. i1 (bool) → zext(1 保持 1,而非 sext 的 0xFF...)
|
||||
2. i8 → zext(系统编程中 i8 几乎总是无符号字节)
|
||||
3. AST 节点解析为无符号类型(t.CUIntXXT 强转/无符号类型名/BYTE 等)→ zext
|
||||
4. 否则 sext
|
||||
"""
|
||||
if val is None or val.Ty is None:
|
||||
return 0
|
||||
bits: int = self.get_llvm_type_bits(val.Ty)
|
||||
if bits == 1:
|
||||
return 1
|
||||
if bits == 8:
|
||||
return 1
|
||||
if node is not None:
|
||||
if self.Gen.ExprGenOps._node_type_unsigned(pool, node) != 0:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
# ============================================================
|
||||
# translate_ptr_arith - 指针算术: ptr + int / ptr - int
|
||||
#
|
||||
|
||||
@@ -110,6 +110,14 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
if ret_ty is None:
|
||||
ret_ty = self.Gen.FuncGenBase._resolve_creturn_ret_ty(
|
||||
pool, fd, imported_modules, from_imports, trans)
|
||||
if ret_ty is None and fd.returns is not None:
|
||||
# 有返回注解但解析失败:编译期报错,不静默回退 i32。
|
||||
# (i32 回退曾导致掉尾检查强制 return i32 / 跨模块调用返回类型错位,
|
||||
# mm.vp free / GetMemoryStats 根因。)无返回注解函数(def foo():)
|
||||
# 保留 i32 默认,不在此报错。
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
fd, "函数返回类型解析失败:注解不可解析", "TypeError")
|
||||
return 0
|
||||
if ret_ty is None:
|
||||
ret_ty = i32_ty
|
||||
|
||||
|
||||
@@ -1,17 +1,8 @@
|
||||
import t, c
|
||||
from stdint import *
|
||||
import ast
|
||||
import lib.Projectrans.Config as Config
|
||||
import lib.Projectrans.Utils as Utils
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.VLogger as VLogger
|
||||
import llvmlite
|
||||
import memhub
|
||||
import stdio
|
||||
import stdlib
|
||||
import string
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.Gen.GenTypes as GenTypes
|
||||
import lib.core.Gen.Generator as Generator
|
||||
import lib.core.Gen.Translator as HT
|
||||
|
||||
@@ -23,12 +23,6 @@ import lib.Stub.StubMerger.StubMergerStore as StubMergerStore
|
||||
# _g_reexport_count/_g_current_file)→ 本类字段
|
||||
# 模块级函数(add_imported_module/is_module_imported/...)→ 本类方法
|
||||
#
|
||||
# 迁移原则(与 P1-P5 Mixin 一致,行为零变化):
|
||||
# 1. 方法保留原函数签名(含 pool 首参),仅函数体内的全局变量改为 self.字段
|
||||
# 2. 本模块内部函数调用改为 self.方法;跨模块调用(StubMerger 等)保留模块前缀
|
||||
# 3. HandlesImports.vp 原函数保留为"委托":本地模块级单例 _g_gen
|
||||
# (BuildPipeline/main 注入)cast 成 Generator 类型后调本类方法
|
||||
#
|
||||
# @t.NoVTable:静态绑定(方法沿 MRO 直接调用 + this 调整,无 vtable 开销)。
|
||||
# ============================================================
|
||||
|
||||
|
||||
@@ -1256,7 +1256,11 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
# 直接返回 None 让上层回落(fail-fast:宁可类型退化
|
||||
# 也不静默卡死)。
|
||||
if string.strcmp(gp_ta, gp_tpn) == 0:
|
||||
return None
|
||||
# 泛型类型参数自映射(T→T):编译期报错,不静默退化。
|
||||
# 此前 return None 让上层静默退化(i32/Ptr(i8)),
|
||||
# 运行时数据损坏难定位(ListTest/DictTest 根因之一)。
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
nm, f"泛型类型实参污染:类型参数 '{gp_tpn}' 自映射(实参='{gp_ta}'),无法特化", "TypeError")
|
||||
polluted: int = 0
|
||||
gp_j: t.CSizeT
|
||||
for gp_j in range(gp_n):
|
||||
@@ -1265,7 +1269,11 @@ class TypeGenResolve(TypeGenBase.TypeGenBase):
|
||||
polluted = 1
|
||||
break
|
||||
if polluted != 0:
|
||||
return None
|
||||
# 实参串包含类型参数名(如 "T | t.CPtr"/"list[T]"):
|
||||
# 解析后仍产出 Name(参数名) → 无条件自递归卡死。编译期
|
||||
# 报错(此前 return None 静默退化)。
|
||||
self.Gen.TypeGenErr.fatal_error(
|
||||
nm, f"泛型类型实参污染:实参 '{gp_ta}' 包含类型参数名,无法特化", "TypeError")
|
||||
# 用具体类型名递归解析(支持 BinOp/Attribute 类型实参)
|
||||
gp_sub_node: ast.AST | t.CPtr = self._parse_type_string(pool, gp_ta, nm.ctx)
|
||||
if gp_sub_node is not None:
|
||||
|
||||
Reference in new issue
Block a user