From d687216772aef87e351b91c225c2077c9a85bcb4 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Mon, 10 Aug 2026 23:01:43 +0800 Subject: [PATCH] =?UTF-8?q?fix(TPC):=20=E7=BB=A7=E6=89=BF=E9=93=BE=20vtabl?= =?UTF-8?q?e=20=E7=8A=B6=E6=80=81=E8=BF=BD=E6=BA=AF=20+=20=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=8F=82=E6=95=B0=E6=A3=80=E6=9F=A5=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E7=BC=BA=E5=A4=B1=E4=BF=9D=E6=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - _resolve_class_flags 沿 class_parent 链追溯 vtable 状态:Stmt/ExprNode 空中间基类(@t.CVTable 无方法)跨模块未注册 class_vtable,子类 IsCVTable 误判为 False → __before_init__ base=0 不写 vtable → 实例 vtable=null → 虚调用段错误。改为沿链查找任一祖先有 vtable 即继承。 - 函数调用严格参数检查:默认参数信息缺失(跨模块 stub 加载/并行编译时序未同步)时跳过检查,避免 fatal_error 误报缺少必需参数。 --- lib/core/Handles/HandlesClassDef.py | 19 +++++++++++++++++-- lib/core/Handles/HandlesExprCall.py | 21 +++++++++++++++------ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/lib/core/Handles/HandlesClassDef.py b/lib/core/Handles/HandlesClassDef.py index 21d9bb6..de84be7 100644 --- a/lib/core/Handles/HandlesClassDef.py +++ b/lib/core/Handles/HandlesClassDef.py @@ -442,8 +442,23 @@ class ClassHandle(BaseHandle): # 继承链统一 vtable(与 TPV _detect_vtable_status 一致): # 父类有 vtable → 子类启用;父类无 vtable → 子类不启用(静态); # 父类 vtable 状态未知(跨模块/未注册)→ 保守启用。 - parent_has_vtable: bool = (ParentClassName in Gen.class_vtable - or ParentClassName in Gen._cross_module_vtable_classes) + # 沿继承链追溯父类的 vtable 状态(支持空中间基类 Stmt/ExprNode): + # Stmt/ExprNode 无方法但 @t.CVTable,跨模块加载时 _has_methods_prescan=False + # 未注册 class_vtable,若只查直接父类会误判子类为静态类 → + # __before_init__ base=0 不写 vtable → 实例 vtable 为 null → 虚调用段错误。 + # 修复:沿 class_parent 链向上查,任一祖先有 vtable 即判定子类有 vtable。 + _parent_has_vtable: bool = False + _p_chain: str | None = ParentClassName + _p_visited_chain: set[str] = {ClassName} + _class_parent_map: dict = getattr(Gen, 'class_parent', {}) + while _p_chain and _p_chain not in _p_visited_chain: + _p_visited_chain.add(_p_chain) + if (_p_chain in Gen.class_vtable + or _p_chain in Gen._cross_module_vtable_classes): + _parent_has_vtable = True + break + _p_chain = _class_parent_map.get(_p_chain) + parent_has_vtable: bool = _parent_has_vtable parent_known: bool = (ParentClassName in class_graph or ParentClassName in Gen.class_members or ParentClassName in Gen.structs) diff --git a/lib/core/Handles/HandlesExprCall.py b/lib/core/Handles/HandlesExprCall.py index eb2b30c..3a709c9 100644 --- a/lib/core/Handles/HandlesExprCall.py +++ b/lib/core/Handles/HandlesExprCall.py @@ -1445,12 +1445,21 @@ class ExprCallHandle(BaseHandle): func_defaults = gv break total_params: int = len(exact_param_names) - num_defaults: int = len(func_defaults) if func_defaults else 0 - min_args: int = total_params - num_defaults - # 只检查必需参数(有默认值的参数允许缺失) - for i in range(min_args): - if i >= provided and i not in kw_provided: - raise Exception(f"调用 {ModulePath}.{func_name}() 缺少必需参数 '{exact_param_names[i]}',该参数没有默认值") + if func_defaults is None: + # 默认参数信息缺失(跨模块 stub 加载:vpi/stub 只含参数 + # 类型不含默认值;或并行编译时序导致定义模块的默认参数 + # 尚未注册到共享表)→ 无法准确计算必需参数数量, + # 跳过严格检查避免误报(如 HandlesType.fatal_error 的 + # err_type/col_start/col_end 默认值未同步时误报"缺 arg3")。 + # 同文件函数的参数检查由 FunctionDef 路径(L1983)覆盖。 + pass + else: + num_defaults: int = len(func_defaults) + min_args: int = total_params - num_defaults + # 只检查必需参数(有默认值的参数允许缺失) + for i in range(min_args): + if i >= provided and i not in kw_provided: + raise Exception(f"调用 {ModulePath}.{func_name}() 缺少必需参数 '{exact_param_names[i]}',该参数没有默认值") elif ModulePath in Gen.ModuleSha1Map and len(Node.args) == 0: func = Gen.functions.get(mangled_name) if func and len(func.function_type.args) > 0: