fix(tpc): 方法调用/属性调用路径的实参不再静默丢弃(收口"整体错位一格")
类别: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 干净;未跑编译器。
This commit is contained in:
1 parent
62cab0f6c1
commit
783aba1e49
1 file changed
+34
-28
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user