From a8eb7fe5fef84a55aa9eb4632a06a75f651a8cf6 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Fri, 28 Aug 2026 14:57:46 +0800 Subject: [PATCH] =?UTF-8?q?fix(tpv):=20=E7=B1=BB=E5=9E=8B=E9=9D=99?= =?UTF-8?q?=E9=BB=98=E9=80=80=E5=8C=96=E6=94=B9=E7=BC=96=E8=AF=91=E6=9C=9F?= =?UTF-8?q?=E6=8A=A5=E9=94=99=20+=20=E7=BB=9F=E4=B8=80=E6=95=B4=E6=95=B0?= =?UTF-8?q?=E6=8B=93=E5=AE=BD=20zext/sext?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 等无符号值被符号扩展的隐蔽数据损坏 --- App/lib/core/Gen/AssignGenMixin.vp | 5 +--- App/lib/core/Gen/Call/CallGenBase.vp | 2 -- App/lib/core/Gen/Call/CallGenCBuiltin.vp | 12 ++------- App/lib/core/Gen/Call/CallGenCall.vp | 14 ++-------- App/lib/core/Gen/Call/CallGenCtor.vp | 8 ++---- App/lib/core/Gen/Call/CallGenDispatch.vp | 3 +-- App/lib/core/Gen/Expr/ExprGenBase.vp | 33 +++++++++++++++++++++--- App/lib/core/Gen/Func/FuncGenDef.vp | 8 ++++++ App/lib/core/Gen/GenApi.vp | 9 ------- App/lib/core/Gen/ImportsGenMixin.vp | 6 ----- App/lib/core/Gen/Type/TypeGenResolve.vp | 12 +++++++-- 11 files changed, 56 insertions(+), 56 deletions(-) diff --git a/App/lib/core/Gen/AssignGenMixin.vp b/App/lib/core/Gen/AssignGenMixin.vp index e6eb1d9..0e4a2a6 100644 --- a/App/lib/core/Gen/AssignGenMixin.vp +++ b/App/lib/core/Gen/AssignGenMixin.vp @@ -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( diff --git a/App/lib/core/Gen/Call/CallGenBase.vp b/App/lib/core/Gen/Call/CallGenBase.vp index ac2e2c9..807da19 100644 --- a/App/lib/core/Gen/Call/CallGenBase.vp +++ b/App/lib/core/Gen/Call/CallGenBase.vp @@ -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 diff --git a/App/lib/core/Gen/Call/CallGenCBuiltin.vp b/App/lib/core/Gen/Call/CallGenCBuiltin.vp index ee463af..30df6e4 100644 --- a/App/lib/core/Gen/Call/CallGenCBuiltin.vp +++ b/App/lib/core/Gen/Call/CallGenCBuiltin.vp @@ -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 # ============================================================ diff --git a/App/lib/core/Gen/Call/CallGenCall.vp b/App/lib/core/Gen/Call/CallGenCall.vp index 73774fd..06ef07f 100644 --- a/App/lib/core/Gen/Call/CallGenCall.vp +++ b/App/lib/core/Gen/Call/CallGenCall.vp @@ -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): diff --git a/App/lib/core/Gen/Call/CallGenCtor.vp b/App/lib/core/Gen/Call/CallGenCtor.vp index 023f1b7..693b651 100644 --- a/App/lib/core/Gen/Call/CallGenCtor.vp +++ b/App/lib/core/Gen/Call/CallGenCtor.vp @@ -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 # ============================================================ diff --git a/App/lib/core/Gen/Call/CallGenDispatch.vp b/App/lib/core/Gen/Call/CallGenDispatch.vp index 8439514..7b63556 100644 --- a/App/lib/core/Gen/Call/CallGenDispatch.vp +++ b/App/lib/core/Gen/Call/CallGenDispatch.vp @@ -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 diff --git a/App/lib/core/Gen/Expr/ExprGenBase.vp b/App/lib/core/Gen/Expr/ExprGenBase.vp index 752f97c..6fd1d75 100644 --- a/App/lib/core/Gen/Expr/ExprGenBase.vp +++ b/App/lib/core/Gen/Expr/ExprGenBase.vp @@ -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 # diff --git a/App/lib/core/Gen/Func/FuncGenDef.vp b/App/lib/core/Gen/Func/FuncGenDef.vp index f3c9229..b1e97f8 100644 --- a/App/lib/core/Gen/Func/FuncGenDef.vp +++ b/App/lib/core/Gen/Func/FuncGenDef.vp @@ -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 diff --git a/App/lib/core/Gen/GenApi.vp b/App/lib/core/Gen/GenApi.vp index 4fc8a9f..5d2b167 100644 --- a/App/lib/core/Gen/GenApi.vp +++ b/App/lib/core/Gen/GenApi.vp @@ -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 diff --git a/App/lib/core/Gen/ImportsGenMixin.vp b/App/lib/core/Gen/ImportsGenMixin.vp index 33ad36d..f98d731 100644 --- a/App/lib/core/Gen/ImportsGenMixin.vp +++ b/App/lib/core/Gen/ImportsGenMixin.vp @@ -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 开销)。 # ============================================================ diff --git a/App/lib/core/Gen/Type/TypeGenResolve.vp b/App/lib/core/Gen/Type/TypeGenResolve.vp index c9eb041..d187936 100644 --- a/App/lib/core/Gen/Type/TypeGenResolve.vp +++ b/App/lib/core/Gen/Type/TypeGenResolve.vp @@ -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: