fix gh-43: type func_num_args expressions

master
韩天峰 1 day ago
parent af466b067c
commit 10ecb94470
  1. 9
      src/Optimizer/FuncCallOptimizer.php
  2. 59
      tests/compiler/functions/func_num_args-return.phpt

@ -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

@ -0,0 +1,59 @@
--TEST--
func_num_args static count can be returned without leaking an ambiguous C++ integer literal
--FILE--
<?php
function staticArgumentCountUntyped($value = null)
{
return func_num_args();
}
function staticArgumentCountTyped($first = null, $second = 5): int
{
return func_num_args();
}
function staticVariadicArgumentCount($first = null, ...$rest)
{
return func_num_args();
}
class StaticArgumentCount
{
public function method($value = null)
{
return func_num_args();
}
public static function staticMethod($value = null): int
{
return func_num_args();
}
}
function main(): void
{
// TypePHP intentionally reports the statically materialized parameter
// slots, including omitted optional parameters filled by their defaults.
var_dump(staticArgumentCountUntyped());
var_dump(staticArgumentCountUntyped(10));
var_dump(staticArgumentCountTyped());
var_dump(staticArgumentCountTyped(10));
var_dump(staticVariadicArgumentCount());
var_dump(staticVariadicArgumentCount(10, 20, 30));
$object = new StaticArgumentCount();
var_dump($object->method());
var_dump(StaticArgumentCount::staticMethod());
}
?>
--EXPECT--
int(1)
int(1)
int(2)
int(2)
int(1)
int(3)
int(1)
int(1)
Loading…
Cancel
Save