fix(tpv): __new__ 调用按被调方签名截掉多余尾参

mlir-opt 报:
  error: 'llvm.call' op incorrect number of operands (8) for callee (expecting: 7)
      %245 = llvm.call @a959d1abdb31a471.FunctionDef.__new__(%35, %239, %240,
             %241, %242, %243, %is_async, %244) : (...) -> !llvm.ptr

定义/声明侧(ast/stmts.vp vpi 核实):
  FunctionDef.__new__(self, pool, name, args, decorator_list, returns, is_async)
      = 7 个形参(非-self 6)
  FunctionDef.__init__(..., is_async, type_params = None)
      = 8 个形参(非-self 7,多出的 type_params 有默认值)

根因:构造器路径把 ctor 实参**全量**转发给 __new__,而 __new__ 的签名比
__init__ 短(无 type_params)⇒ 调用点传了 7 个非-self 实参,声明只收 6 个。
(临时探针实测:mdf_param_count=6 正确、封参逻辑未触发,extra_count=7 才是不匹配源。)

修复:_call_method_on_ptr 中对 method_name == "__new__" 且已找到 declare 时,按被调方
非-self 形参数截掉多余**尾参**(这些尾参 __new__ 本就不接收,语义上由 __init__
消费;__new__ 只负责分配存储)。探针已删除。

验证:python ./TransPyC/Projectrans.py --project ./TransPyV/project.vpj --clean
      --rebuild-includes --clear-cache 重编通过;
      ./TransPyV/output/TransPyV.exe --project ./Test/SlotsBugTest/project.json
      PhaseB 编译完成 → PhaseC 产出 SlotsBugTest.exe → TransPyV 完成。
This commit is contained in:
TermiNexus committed 2026-10-04 20:09:21 +08:00
1 parent 6a6cae2a44
commit 58cfe2346e
1 file changed
+16
+16
View File
@@ -385,6 +385,22 @@ novirtual class CallGenCall(CallGenBase.CallGenBase):
self.Gen.TypeGenErr.fatal_error(node, err_cm4)
self.Gen.TypeGenErr.fatal_error(node, "方法返回类型无法确定")
# __new__ 的签名可能**短于** __init__:ctor 路径把 ctor 实参**全量**转发给
# __new__,会多传尾参 ⇒ call 实参数 > declare 形参数
# (mlir-opt: "llvm.call op incorrect number of operands (8) for callee
# (expecting: 7)";现场 ast.FunctionDef.__new__ 无 type_params,而
# __init__ 有 `type_params = None`,调用点仍按 ctor 全量传 7 个)。
# 按被调方(declare/vpi 解析出的)非-self 形参数**截掉尾参**:这些尾参
# __new__ 本就不接收,语义上由 __init__ 消费(__new__ 只负责分配存储)。
if string.strcmp(method_name, "__new__") == 0 and found_func is not None:
nn_pc: int = 0
nn_pn: mlirlite.Param* = mlirlite.function_get_param_head(found_func)
while nn_pn is not None:
nn_pc += 1
nn_pn = mlirlite.param_get_next(nn_pn)
if nn_pc > 1 and extra_count > nn_pc - 1:
extra_count = nn_pc - 1
# 构建参数链表: self_ptr → extra_args...
mlirlite.value_set_next(self_ptr, None)
head: mlirlite.Value* = self_ptr