diff --git a/src/Optimizer/FuncCallOptimizer.php b/src/Optimizer/FuncCallOptimizer.php index aecdafd6..938bbfaa 100644 --- a/src/Optimizer/FuncCallOptimizer.php +++ b/src/Optimizer/FuncCallOptimizer.php @@ -892,6 +892,13 @@ protected function dispatchBigType( $args[] = $this->parseOrderedOperand($expr->args[1]->value, false); } + // PHP abs(PHP_INT_MIN) returns a float. The scalar PHPX overload + // cannot represent that value-dependent return type, so route static + // integers through the Variant overload, which preserves it. + if ($target === 'php::fn::abs' && $type === Type::INT) { + return $target . '(php::Variant(' . $args[0] . '))'; + } + return $target . '(' . implode(', ', $args) . ')'; } diff --git a/tests/compiler/static/static_prop_write.phpt b/tests/compiler/static/static_prop_write.phpt index d25a74a8..8827d81f 100644 --- a/tests/compiler/static/static_prop_write.phpt +++ b/tests/compiler/static/static_prop_write.phpt @@ -29,4 +29,4 @@ function main() { } ?> --EXPECT-- -string(4) "init" \ No newline at end of file +string(27) "{closure:Worker::init():18}" diff --git a/tests/compiler/stdlib/abs_edge.phpt b/tests/compiler/stdlib/abs_edge.phpt index ca51ed37..ef167f60 100644 --- a/tests/compiler/stdlib/abs_edge.phpt +++ b/tests/compiler/stdlib/abs_edge.phpt @@ -1,16 +1,45 @@ --TEST-- -abs edge cases: PHP_INT_MIN and -0.0 +abs edge cases preserve PHP_INT_MIN's float result on static integer paths --FILE-- --EXPECT-- float(9.223372036854776E+18) +float(9.223372036854776E+18) +int(42) +float(9.223372036854776E+18) +int(1) +float(9.223372036854776E+18) float(0) int(0) int(5)