fix(call): 实参个数与被调方不符时前端 fail-fast - 不再漏到 LLVM verifier(含 EH 参数扣除与可变参数放行)

This commit is contained in:
TermiNexus committed 2026-10-16 19:26:22 +08:00
1 parent 2f4031b3d6
commit 19feb40e8c
1 file changed
+17
+17
View File
@@ -117,6 +117,23 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
# ============================================================
def _emit_eh_guarded_call(self, builder: mlirlite.IRBuilder*, pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, trans: HT.Translator*, func: mlirlite.Function*, call_name: str, head: mlirlite.Value*, count: int, ret_ty: mlirlite.LLVMType*, is_variadic: int) -> mlirlite.Value*:
"""Call a function with try-except EH detection; returns the call result (positioned at ok block)"""
# Argument-count check (fail-fast at the front end instead of leaking to the LLVM verifier).
# Callee params include the injected EH out-params (%__eh_msg_out__/__eh_code_out__), which the
# caller does not pass explicitly (they are appended later in this function), so subtract them.
if func is not None and is_variadic == 0:
n_declared: int = 0
p_chk: mlirlite.Param* = mlirlite.function_get_param_head(func)
while p_chk is not None:
n_declared += 1
p_chk = mlirlite.param_get_next(p_chk)
if self._func_has_eh_params(func) == 1: n_declared = n_declared - 2
if n_declared >= 0 and count != n_declared:
fname_chk: str = mlirlite.function_get_name(func)
if fname_chk is None: fname_chk = call_name
self.Gen.TypeGenErr.fatal_error(
None,
f"Argument count mismatch calling '{fname_chk}': the callee declares {n_declared} parameter(s) but the call passes {count} argument(s)",
"TypeError")
if trans is None or self._func_has_eh_params(func) == 0: return mlirlite.build_call(builder, call_name, head, count, ret_ty, is_variadic)
# ---- 1. determine output pointers ----
i8_ty_g: mlirlite.LLVMType* = mlirlite.Int8(pool)