From 783aba1e49c26dc2bd8873533efd5946c406cea2 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Tue, 29 Sep 2026 17:01:14 +0800 Subject: [PATCH] =?UTF-8?q?fix(tpc):=20=E6=96=B9=E6=B3=95=E8=B0=83?= =?UTF-8?q?=E7=94=A8/=E5=B1=9E=E6=80=A7=E8=B0=83=E7=94=A8=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E7=9A=84=E5=AE=9E=E5=8F=82=E4=B8=8D=E5=86=8D=E9=9D=99?= =?UTF-8?q?=E9=BB=98=E4=B8=A2=E5=BC=83=EF=BC=88=E6=94=B6=E5=8F=A3"?= =?UTF-8?q?=E6=95=B4=E4=BD=93=E9=94=99=E4=BD=8D=E4=B8=80=E6=A0=BC"?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 类别:a(编译器缺陷)—— 实参求值为空被静默丢弃 ⇒ 后续实参整体前移一格 ⇒ 报出与 真因无关的类型不匹配。 现场(TransPyV/App/lib/core/Gen/Func/FuncGenMixin.vp:1429): `return self._lambda_scan_body(trans, ie.orelse, param_names, param_count, cap_names, cap_allocas, cap_tys, cc6)` → `_adjust_args` 报"指针类型 i8* 不能隐式转换为整数参数 i32"。 判据(把报文的"逐项"列表与两种假设逐位对照): 形参表(stub declare,与该行源码一致): self, trans, node=%AST*, param_names=i8*, param_count=i32, cap_names=i8*, cap_allocas=i8*, cap_tys=i8*, cap_count=i32 实测实参:i8*, i32, i8*, i8*, i8*, i32, i32(9 项) 假设"第 3 个实参(param_names,i8*)被丢弃、末尾由 _fill_default_args 补 cap_count 的零值 i32"⇒ 预测 arg[2..8]=orelse(i8*), param_count(i32), cap_names(i8*), cap_allocas(i8*), cap_tys(i8*), cc6(i32), 补零(i32) ⇒ **与实测逐位完全一致**。反证:若丢的是末尾的 cc6,预测序列与实测不符。 (`_fill_default_args` 只从**末尾**按形参类型补零:HandlesExprCall.py:202-248) 修复:方法调用路径(_HandleMethodCallLlvm)与属性调用回退路径(_HandleCallLlvm) 共 7 处仍写作 `ArgVal = HandleExprLlvm(arg); if ArgVal: append(ArgVal)` —— 正是 `_RequireArgValue` 文档里点名要收口的旧写法(此前只收口了 4 处类构造)。现全部 改为 `_RequireArgValue(...)`:实参求值为空当场 fail-fast,报文含被调者、实参序号与 源表达式,**不丢弃该实参**。 同族未收口(本次不动,逐条记录):`_ApplyKeywordArgs` 的关键字实参(:337)、 `:595` 的 UserCallArgs、`:1262`、`:1336` 共 4 处仍是旧写法。 验证:GetDiagnostics 干净;未跑编译器。 --- lib/core/Handles/HandlesExprCall.py | 62 ++++++++++++++++------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/lib/core/Handles/HandlesExprCall.py b/lib/core/Handles/HandlesExprCall.py index 052c010..0da4df0 100644 --- a/lib/core/Handles/HandlesExprCall.py +++ b/lib/core/Handles/HandlesExprCall.py @@ -1036,10 +1036,11 @@ class ExprCallHandle(BaseHandle): mangled_name = Gen._mangle_func_name(FuncAttr, ModulePath if ModulePath and ModulePath != 't' else None) if Gen._has_function(mangled_name): CallArgs = [] - for arg in Node.args: - ArgVal = self.HandleExprLlvm(arg) - if ArgVal: - CallArgs.append(ArgVal) + for ArgIdx, arg in enumerate(Node.args, start=1): + # 禁止静默丢弃求值为空的实参(会导致后续整体前移一格, + # 报出与真因无关的类型不匹配,见 _RequireArgValue 说明) + CallArgs.append(self._RequireArgValue( + self.HandleExprLlvm(arg), FuncAttr, ArgIdx, arg, Node)) return Gen.builder.call(Gen._get_function(mangled_name), CallArgs, name=f"call_{FuncAttr}") if MethodResult is None or IsZeroResult: imported = getattr(self.Trans, '_ImportedModules', set()) @@ -1083,10 +1084,10 @@ class ExprCallHandle(BaseHandle): fallback_func = Gen._find_function(FuncAttr) if fallback_func is not None: CallArgs = [] - for arg in Node.args: - ArgVal = self.HandleExprLlvm(arg) - if ArgVal: - CallArgs.append(ArgVal) + for ArgIdx, arg in enumerate(Node.args, start=1): + # 同 1039:禁止静默丢弃(会导致后续前移一格) + CallArgs.append(self._RequireArgValue( + self.HandleExprLlvm(arg), FuncAttr, ArgIdx, arg, Node)) self._append_eh_msg_out_arg(CallArgs, fallback_func, Gen) result = Gen.builder.call(fallback_func, CallArgs, name=f"call_{FuncAttr}") return self._check_eh_return(result, FuncAttr, Gen, called_func=fallback_func) @@ -1107,10 +1108,10 @@ class ExprCallHandle(BaseHandle): decl_name = stub_mangled if stub_mangled in getattr(self.Trans.ImportHandler, '_stub_func_cache', {}) else FuncAttr func_decl = self.GetOrCreateStubFuncDecl(decl_name, stub_func_type, Gen, alias=FuncAttr) CallArgs = [] - for arg in Node.args: - ArgVal = self.HandleExprLlvm(arg) - if ArgVal: - CallArgs.append(ArgVal) + for ArgIdx, arg in enumerate(Node.args, start=1): + # 同 1039:禁止静默丢弃(会导致后续前移一格) + CallArgs.append(self._RequireArgValue( + self.HandleExprLlvm(arg), FuncAttr, ArgIdx, arg, Node)) self._append_eh_msg_out_arg(CallArgs, func_decl, Gen) result = Gen.builder.call(func_decl, CallArgs, name=f"call_{FuncAttr}") return self._check_eh_return(result, FuncAttr, Gen, called_func=func_decl) @@ -3356,10 +3357,13 @@ class ExprCallHandle(BaseHandle): _ptypes: list[ir.Type] = func.function_type.args if func is not None else [] for _ai, arg in enumerate(Node.args): _pt: ir.Type | None = _ptypes[_ai] if _ai < len(_ptypes) else None - ArgVal = self.HandleExprLlvm( - arg, ConstWidthHint=DefineUseWidthFromLLVMType(_pt)) - if ArgVal: - CallArgs.append(ArgVal) + # 不再 `if ArgVal: append`(实参求值为空会被静默丢弃 ⇒ 后续整体 + # 前移一格 ⇒ 由 _adjust_args 报出与真因无关的类型不匹配,见 + # _RequireArgValue 的说明)。 + CallArgs.append(self._RequireArgValue( + self.HandleExprLlvm( + arg, ConstWidthHint=DefineUseWidthFromLLVMType(_pt)), + mangled_name, _ai + 1, arg, Node)) self._fill_default_args(CallArgs, func, MethodName) func_ft = getattr(func, 'function_type', None) is_variadic = getattr(func_ft, 'var_arg', False) if func_ft else False @@ -3415,10 +3419,11 @@ class ExprCallHandle(BaseHandle): _ptypes: list[ir.Type] = _mf.function_type.args for _ai, arg in enumerate(Node.args): _pt: ir.Type | None = _ptypes[_ai] if _ai < len(_ptypes) else None - ArgVal = self.HandleExprLlvm( - arg, ConstWidthHint=DefineUseWidthFromLLVMType(_pt)) - if ArgVal: - CallArgs.append(ArgVal) + # 同 3357:禁止静默丢弃求值为空的实参(会导致后续前移一格) + CallArgs.append(self._RequireArgValue( + self.HandleExprLlvm( + arg, ConstWidthHint=DefineUseWidthFromLLVMType(_pt)), + MethodName, _ai + 1, arg, Node)) func = _mf self._fill_default_args(CallArgs, func, MethodName) func_ft = getattr(func, 'function_type', None) @@ -3484,10 +3489,11 @@ class ExprCallHandle(BaseHandle): _ptypes: list[ir.Type] = func.function_type.args if func is not None else [] for _ai, arg in enumerate(Node.args): _pt: ir.Type | None = _ptypes[_ai] if _ai < len(_ptypes) else None - ArgVal = self.HandleExprLlvm( - arg, ConstWidthHint=DefineUseWidthFromLLVMType(_pt)) - if ArgVal: - CallArgs.append(ArgVal) + # 同 3357:禁止静默丢弃求值为空的实参(会导致后续前移一格) + CallArgs.append(self._RequireArgValue( + self.HandleExprLlvm( + arg, ConstWidthHint=DefineUseWidthFromLLVMType(_pt)), + mangled_name, _ai + 1, arg, Node)) self._fill_default_args(CallArgs, func, mangled_name) self._append_eh_msg_out_arg(CallArgs, func, Gen) CallArgs = Gen._apply_auto_addr(mangled_name, CallArgs) @@ -3497,10 +3503,10 @@ class ExprCallHandle(BaseHandle): return result return ir.Constant(ir.IntType(32), 0) CallArgs = [] - for arg in Node.args: - ArgVal = self.HandleExprLlvm(arg) - if ArgVal: - CallArgs.append(ArgVal) + for _ai, arg in enumerate(Node.args): + # 同 3357:禁止静默丢弃求值为空的实参(会导致后续整体前移一格) + CallArgs.append(self._RequireArgValue( + self.HandleExprLlvm(arg), self._ExprText(Node.func), _ai + 1, arg, Node)) ClassName = None if isinstance(Node.func.value, ast.Name): ClassName = Gen.var_struct_class.get(Node.func.value.id)