fix(optimizer): fold function aliases using resolved names (#88)

master
yavon007 1 month ago committed by GitHub
parent cbd100f906
commit 5488805baf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 25
      src/Optimizer/FuncCallOptimizer.php
  2. 37
      tests/compiler/namespace/use-function-alias-constant-folding.phpt

@ -505,7 +505,7 @@ trait FuncCallOptimizer
}
if (isset($config['constFold'])) {
$folded = $this->tryConstFold($config['constFold'], $config['constFoldExtra'] ?? null, $expr);
$folded = $this->tryConstFold($name, $config['constFold'], $config['constFoldExtra'] ?? null, $expr);
if ($folded !== false) {
return $folded;
}
@ -896,13 +896,13 @@ trait FuncCallOptimizer
// Constant folding
// =========================================================================
protected function tryConstFold(int $rule, mixed $extra, Node\Expr\FuncCall $expr): string|false
protected function tryConstFold(string $name, int $rule, mixed $extra, Node\Expr\FuncCall $expr): string|false
{
return match ($rule) {
self::FOLD_STRING_LEN => $this->doFoldStringLen($expr),
self::FOLD_STRING_CASE => $this->doFoldStringCase($expr),
self::FOLD_CMP2 => $this->doFoldCmp2($expr),
self::FOLD_CMP3 => $this->doFoldCmp3($expr),
self::FOLD_STRING_CASE => $this->doFoldStringCase($name, $expr),
self::FOLD_CMP2 => $this->doFoldCmp2($name, $expr),
self::FOLD_CMP3 => $this->doFoldCmp3($name, $expr),
self::FOLD_COUNT_LITERAL => $this->doFoldCountLiteral($expr),
self::FOLD_KNOWN_CLASS => $this->doFoldKnownClass($expr),
self::FOLD_KNOWN_CONSTANT => $this->doFoldKnownConstant($expr),
@ -919,32 +919,30 @@ trait FuncCallOptimizer
: false;
}
protected function doFoldStringCase(Node\Expr\FuncCall $expr): string|false
protected function doFoldStringCase(string $name, Node\Expr\FuncCall $expr): string|false
{
$arg = $expr->args[0]->value;
if (!$this->isScalarString($arg)) {
return false;
}
$func = $expr->name instanceof Node\Name ? $expr->name->toLowerString() : '';
$val = $func === 'strtoupper' ? strtoupper($arg->value) : strtolower($arg->value);
$val = $name === 'strtoupper' ? strtoupper($arg->value) : strtolower($arg->value);
return $this->getLiteralString($val);
}
protected function doFoldCmp2(Node\Expr\FuncCall $expr): string|false
protected function doFoldCmp2(string $name, Node\Expr\FuncCall $expr): string|false
{
$a0 = $expr->args[0]->value;
$a1 = $expr->args[1]->value;
if (!$this->isScalarString($a0) || !$this->isScalarString($a1)) {
return false;
}
$func = $expr->name instanceof Node\Name ? $expr->name->toLowerString() : '';
$result = $func === 'strcasecmp'
$result = $name === 'strcasecmp'
? strcasecmp($a0->value, $a1->value)
: strcmp($a0->value, $a1->value);
return $result . $this->getPlatform()->getIntegerLiteralSuffix();
}
protected function doFoldCmp3(Node\Expr\FuncCall $expr): string|false
protected function doFoldCmp3(string $name, Node\Expr\FuncCall $expr): string|false
{
$a0 = $expr->args[0]->value;
$a1 = $expr->args[1]->value;
@ -952,8 +950,7 @@ trait FuncCallOptimizer
if (!$this->isScalarString($a0) || !$this->isScalarString($a1) || !$this->isScalarInt($a2)) {
return false;
}
$func = $expr->name instanceof Node\Name ? $expr->name->toLowerString() : '';
$result = $func === 'strncasecmp'
$result = $name === 'strncasecmp'
? strncasecmp($a0->value, $a1->value, (int) $a2->value)
: strncmp($a0->value, $a1->value, (int) $a2->value);
return $result . $this->getPlatform()->getIntegerLiteralSuffix();

@ -0,0 +1,37 @@
--TEST--
Constant folding uses resolved function names for imported aliases
--FILE--
<?php
namespace FunctionAliasFolding {
use function strtoupper as upper;
use function strtolower as strtoupper;
use function strcasecmp as compare;
use function strcmp as strcasecmp;
use function strncasecmp as compare_prefix;
use function strncmp as strncasecmp;
function run(): void
{
var_dump(upper('MiXeD'));
var_dump(strtoupper('MiXeD'));
var_dump(compare('A', 'a'));
var_dump(strcasecmp('A', 'a') !== 0);
var_dump(compare_prefix('A', 'a', 1));
var_dump(strncasecmp('A', 'a', 1) !== 0);
}
}
namespace {
function main(): void
{
FunctionAliasFolding\run();
}
}
?>
--EXPECT--
string(5) "MIXED"
string(5) "mixed"
int(0)
bool(true)
int(0)
bool(true)
Loading…
Cancel
Save