From 10ecb944705e0c93b0d295ef1b0855c692ffb9ba Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 1 Sep 2026 15:10:00 +0800 Subject: [PATCH] fix gh-43: type func_num_args expressions --- src/Optimizer/FuncCallOptimizer.php | 9 ++- .../functions/func_num_args-return.phpt | 59 +++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 tests/compiler/functions/func_num_args-return.phpt diff --git a/src/Optimizer/FuncCallOptimizer.php b/src/Optimizer/FuncCallOptimizer.php index 43b148dd..54e030e8 100644 --- a/src/Optimizer/FuncCallOptimizer.php +++ b/src/Optimizer/FuncCallOptimizer.php @@ -1137,10 +1137,15 @@ trait FuncCallOptimizer $funcDef = $this->functionDef; foreach ($funcDef->argInfoList as $i => $argInfo) { if ($argInfo->variadic) { - return '(' . $argInfo->name . '.count() + ' . $i . ')'; + // Array::count() is size_t, while func_num_args() is a PHP + // integer. Keep the folded expression in the exact native + // type so a surrounding toInt() cannot hit ambiguous C++ + // scalar overloads. + return '(static_cast<' . Type::INT . '>(' . $argInfo->name . '.count()) + ' + . $this->genIntegerLiteral($i) . ')'; } } - return (string) count($funcDef->argInfoList); + return $this->genIntegerLiteral(count($funcDef->argInfoList)); } protected function genFunctionExists(string $name, Node\Expr\FuncCall $expr, array $config): string|false diff --git a/tests/compiler/functions/func_num_args-return.phpt b/tests/compiler/functions/func_num_args-return.phpt new file mode 100644 index 00000000..7858d8e0 --- /dev/null +++ b/tests/compiler/functions/func_num_args-return.phpt @@ -0,0 +1,59 @@ +--TEST-- +func_num_args static count can be returned without leaking an ambiguous C++ integer literal +--FILE-- +method()); + var_dump(StaticArgumentCount::staticMethod()); +} +?> +--EXPECT-- +int(1) +int(1) +int(2) +int(2) +int(1) +int(3) +int(1) +int(1)