From 2a69a344942bb1a139303a361af5e1cf630d8380 Mon Sep 17 00:00:00 2001 From: Jan Nedbal Date: Wed, 24 Apr 2024 16:23:38 +0200 Subject: [PATCH 1/2] ExponentiateHelper: fix internal error and internal warning --- src/Type/ExponentiateHelper.php | 9 ++++++++- tests/PHPStan/Analyser/data/pow.php | 3 +++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Type/ExponentiateHelper.php b/src/Type/ExponentiateHelper.php index 4e62ed9a5d..9a1d10b6f3 100644 --- a/src/Type/ExponentiateHelper.php +++ b/src/Type/ExponentiateHelper.php @@ -4,8 +4,10 @@ use PHPStan\Type\Constant\ConstantFloatType; use PHPStan\Type\Constant\ConstantIntegerType; +use Throwable; use function is_float; use function is_int; +use function pow; final class ExponentiateHelper { @@ -95,7 +97,12 @@ private static function exponentiateConstantScalar(ConstantScalarType $base, Typ } if ($exponent instanceof ConstantScalarType) { - $result = $base->getValue() ** $exponent->getValue(); + try { + // @ to avoid "Warning: A non-numeric value encountered" + $result = @pow($base->getValue(), $exponent->getValue()); // @phpstan-ignore-line + } catch (Throwable) { + return new ErrorType(); + } if (is_int($result)) { return new ConstantIntegerType($result); } diff --git a/tests/PHPStan/Analyser/data/pow.php b/tests/PHPStan/Analyser/data/pow.php index 82f03b1bae..c768eb4be4 100644 --- a/tests/PHPStan/Analyser/data/pow.php +++ b/tests/PHPStan/Analyser/data/pow.php @@ -169,6 +169,9 @@ function doFoo(int $intA, int $intB, string $s, bool $bool, $numericS, float $fl assertType('*ERROR*', $s ** $arr); assertType('*ERROR*', $s ** []); + assertType('4', '4a' ** 1); + assertType('*ERROR*', 'a' ** 1); + assertType('1', pow($bool, 0)); assertType('1', $bool ** '0'); assertType('1', $bool ** false); From 1e2cef85e27e2cd6c545a5a722fd4cad4f8cc843 Mon Sep 17 00:00:00 2001 From: Jan Nedbal Date: Wed, 24 Apr 2024 17:00:35 +0200 Subject: [PATCH 2/2] php8 vs php7 fix --- tests/PHPStan/Analyser/NodeScopeResolverTest.php | 5 +++++ tests/PHPStan/Analyser/data/pow-php7.php | 8 ++++++++ tests/PHPStan/Analyser/data/pow-php8.php | 8 ++++++++ tests/PHPStan/Analyser/data/pow.php | 3 --- 4 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 tests/PHPStan/Analyser/data/pow-php7.php create mode 100644 tests/PHPStan/Analyser/data/pow-php8.php diff --git a/tests/PHPStan/Analyser/NodeScopeResolverTest.php b/tests/PHPStan/Analyser/NodeScopeResolverTest.php index 574004643e..2c8a2befe6 100644 --- a/tests/PHPStan/Analyser/NodeScopeResolverTest.php +++ b/tests/PHPStan/Analyser/NodeScopeResolverTest.php @@ -191,6 +191,11 @@ public function dataFileAsserts(): iterable yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-1014.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-pr-339.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/pow.php'); + if (PHP_VERSION_ID >= 80000) { + yield from $this->gatherAssertTypes(__DIR__ . '/data/pow-php8.php'); + } else { + yield from $this->gatherAssertTypes(__DIR__ . '/data/pow-php7.php'); + } yield from $this->gatherAssertTypes(__DIR__ . '/data/throw-expr.php'); yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-5351.php'); diff --git a/tests/PHPStan/Analyser/data/pow-php7.php b/tests/PHPStan/Analyser/data/pow-php7.php new file mode 100644 index 0000000000..0e068ccabc --- /dev/null +++ b/tests/PHPStan/Analyser/data/pow-php7.php @@ -0,0 +1,8 @@ +