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: