Merge pull request #21 from AlessioGiacobbe/fix/fold-side-effects

fix(optimizer): keep argument side effects when folding is_int/is_float/is_bool
master
韩天峰 9 hours ago committed by GitHub
commit dfeb71dbb5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 11
      src/Optimizer/FuncCallOptimizer.php
  2. 44
      tests/compiler/optimizations/is-type-fold-side-effects.phpt

@ -681,7 +681,16 @@ trait FuncCallOptimizer
if (count($expr->args) !== 1 || !($expr->args[0] instanceof Node\Arg)) {
return false;
}
return ($this->detectTypeOfExpr($expr->args[0]->value) === $expectType) ? 'true' : false;
$value = $expr->args[0]->value;
if ($this->detectTypeOfExpr($value) !== $expectType) {
return false;
}
if ($value instanceof Node\Expr\Variable || $value instanceof Node\Scalar) {
return 'true';
}
// The argument can carry side effects (a call, an increment). Keep
// evaluating it, as genIsNull does for native scalar operands.
return '((void) (' . $this->parseExprAsValue($value) . '), true)';
}
// =========================================================================

@ -0,0 +1,44 @@
--TEST--
Folded is_int/is_float/is_bool must keep evaluating side-effect arguments
--FILE--
<?php
function intSource(): int
{
echo "int-called\n";
return 42;
}
function floatSource(): float
{
echo "float-called\n";
return 1.5;
}
function boolSource(): bool
{
echo "bool-called\n";
return true;
}
function main(): void
{
if (is_int(intSource())) {
echo "is-int\n";
}
echo is_float(floatSource()) ? "is-float\n" : "not-float\n";
$r = is_bool(boolSource());
echo $r ? "is-bool\n" : "not-bool\n";
// Plain variables still fold without extra evaluation.
$n = 7;
echo is_int($n) ? "var-int\n" : "var-not-int\n";
}
?>
--EXPECT--
int-called
is-int
float-called
is-float
bool-called
is-bool
var-int
Loading…
Cancel
Save