From 75ea6fb9b237cae4d2addc2a740996a2c3c2f6d5 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Mon, 28 Sep 2026 20:20:56 +0800 Subject: [PATCH] =?UTF-8?q?fix(transpyv):=20=E6=B6=88=E9=99=A4=E9=9A=90?= =?UTF-8?q?=E5=BC=8F=E5=90=91=E4=B8=8B=E8=BD=AC=E5=9E=8B=EF=BC=88ast.AST*?= =?UTF-8?q?=20=E5=AE=9E=E5=8F=82=20=E2=86=92=20=E6=B4=BE=E7=94=9F=20AST=20?= =?UTF-8?q?=E5=BD=A2=E5=8F=82=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit c 源码违规(严格指针规则:基类指针传派生类形参属向下转型,须显式转换): 1) TranslatorGenMixin._prescan_funcdef_signatures:形参由 ast.FunctionDef* 改为 ast.AST*,函数体内显式 `fd: ast.FunctionDef* = ast.FunctionDef*(node)`。 理由:模块级调度器只持有 ast.AST* 子节点,同一处调用的 translate_function_def / translate_class_def / _register_cexport_from_funcdef 形参一律是 ast.AST*,本函数是唯一例外(报错现场:第 2 个实参 %"..AST"* 不能 隐式转为形参 %"..FunctionDef"*)。改为与兄弟入口同口径,调用点无需改动。 2) CallGenDispatch len() 内置分支:_is_list_builtin_receiver 第 5 形参是 ast.Call*(仅用于 D25 fail-fast 定位节点),实参 len_arg_node 声明为基类 ast.AST* ⇒ 显式窄化 `len_arg_cl: ast.Call* = ast.Call*(len_arg_node)`。 附:对 App\lib 全量静态扫描(core\Gen 全 47 文件 + Stub/Phase/core/main)确认 此类「基类指针实参 → 派生形参」的隐式向下转型仅此两处,其余调用点均为同类型 或向上转型(规则允许)。 同文件另含仓库内既有书写整理(续行合并),无行为变化。 --- App/lib/core/Gen/Call/CallGenDispatch.vp | 18 +++++++++++------- App/lib/core/Gen/TranslatorGenMixin.vp | 11 +++++++++-- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/App/lib/core/Gen/Call/CallGenDispatch.vp b/App/lib/core/Gen/Call/CallGenDispatch.vp index 20a7d9e..59a4944 100644 --- a/App/lib/core/Gen/Call/CallGenDispatch.vp +++ b/App/lib/core/Gen/Call/CallGenDispatch.vp @@ -18,10 +18,10 @@ import lib.core.Gen.Type.TypeSpec as TSpec import lib.Stub.StubMerger as StubMerger import lib.core.CompilerFactory as CompilerFactory from . import CallGenBase -import lib.core.Gen.GenApi as GenApi - - -# ============================================================ +import lib.core.Gen.GenApi as GenApi + + +# ============================================================ # CallGenDispatch - CallGenMixin 拆分(阶段 C):translate_call 检测段 # # 继承 CallGenBase(1 级,TPV self 调用仅支持 1 级父类)。 @@ -813,15 +813,19 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase): # - 普通类:调用 {Class}.__len__ 函数 # - 都没有:fatal_error # str(Ptr(Int8))保持 strlen(内建语义)。 - len_struct_ty: llvmlite.LLVMType* = \ - self.Gen.StructGen.get_struct_type_from_value(len_val) + len_struct_ty: llvmlite.LLVMType* = self.Gen.StructGen.get_struct_type_from_value(len_val) if len_struct_ty is not None: len_cls_nm: str = self.Gen.StructGen.get_class_name_by_type(pool, len_struct_ty) if len_cls_nm is None: self.Gen.TypeGenErr.fatal_error(len_arg_node, "len() 参数类型推断失败(结构体类名未知)", "TypeError") # list 内置 __len__:读 __count__(GEP 偏移 1,i64) # 判据优先取接收者实际类型(_is_list_builtin_receiver) - if self.Gen.CallGenProp._is_list_builtin_receiver(pool, len_val, len_cls_nm, "__len__", len_arg_node) != 0: + # 目标类型已由 can==1(len 的实参存在)确定为表达式节点 + # ⇒ 在此显式窄化:形参是 ast.Call*(仅用于 fail-fast + # 定位节点),而 len_arg_node 声明为基类 ast.AST*; + # 基类指针传派生类形参属向下转型,严格指针规则下禁止。 + len_arg_cl: ast.Call* = ast.Call*(len_arg_node) + if self.Gen.CallGenProp._is_list_builtin_receiver(pool, len_val, len_cls_nm, "__len__", len_arg_cl) != 0: i64_ty_lb: llvmlite.LLVMType* = llvmlite.Int64(pool) idx_one_lb: llvmlite.Value* = llvmlite.const_int64(pool, 1) cnt_ptr_lb: llvmlite.Value* = llvmlite.build_gep(builder, i64_ty_lb, len_val, idx_one_lb) diff --git a/App/lib/core/Gen/TranslatorGenMixin.vp b/App/lib/core/Gen/TranslatorGenMixin.vp index 83c341a..aa613ba 100644 --- a/App/lib/core/Gen/TranslatorGenMixin.vp +++ b/App/lib/core/Gen/TranslatorGenMixin.vp @@ -133,9 +133,16 @@ novirtual class TranslatorGenMixin: # 避免 Phase2 翻译 App 文件时访问悬空结构体(UAF)。 # 仅解析类型触发特化,不验证结果(1b 全量翻译时重新解析)。 # ============================================================ - def _prescan_funcdef_signatures(self, trans: HT.Translator*, fd: ast.FunctionDef*) -> None: + def _prescan_funcdef_signatures(self, trans: HT.Translator*, node: ast.AST*) -> None: """预解析模块级函数签名的返回/参数类型,触发泛型类特化""" - if trans is None or fd is None: + if trans is None or node is None: + return + # 入口收基类 ast.AST*(模块级调度器只持有 ast.AST* 子节点,与同一处调用的 + # translate_function_def / translate_class_def / _register_cexport_from_funcdef + # 形参口径一致),在此显式窄化为 ast.FunctionDef*:基类指针传派生类形参属 + # 向下转型,严格指针规则下禁止隐式转换。 + fd: ast.FunctionDef* = ast.FunctionDef*(node) + if fd is None: return pool: memhub.MemBuddy* = trans.Pool if pool is None: