Skip to content

Commit

Permalink
Fix internal error with a big number in for loop condition
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Jan 28, 2022
1 parent 06864d1 commit f1734dc
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
26 changes: 26 additions & 0 deletions src/Analyser/MutatingScope.php
Original file line number Diff line number Diff line change
Expand Up @@ -5409,15 +5409,24 @@ private function integerRangeMath(Type $range, Expr $node, Type $operand): Type

if ($node instanceof Node\Expr\BinaryOp\Plus || $node instanceof Node\Expr\AssignOp\Plus) {
if ($operand instanceof ConstantIntegerType) {
/** @var int|float|null $min */
$min = $rangeMin !== null ? $rangeMin + $operand->getValue() : null;

/** @var int|float|null $max */
$max = $rangeMax !== null ? $rangeMax + $operand->getValue() : null;
} else {
/** @var int|float|null $min */
$min = $rangeMin !== null && $operand->getMin() !== null ? $rangeMin + $operand->getMin() : null;

/** @var int|float|null $max */
$max = $rangeMax !== null && $operand->getMax() !== null ? $rangeMax + $operand->getMax() : null;
}
} elseif ($node instanceof Node\Expr\BinaryOp\Minus || $node instanceof Node\Expr\AssignOp\Minus) {
if ($operand instanceof ConstantIntegerType) {
/** @var int|float|null $min */
$min = $rangeMin !== null ? $rangeMin - $operand->getValue() : null;

/** @var int|float|null $max */
$max = $rangeMax !== null ? $rangeMax - $operand->getValue() : null;
} else {
if ($rangeMin === $rangeMax && $rangeMin !== null
Expand All @@ -5429,8 +5438,10 @@ private function integerRangeMath(Type $range, Expr $node, Type $operand): Type
$min = null;
} elseif ($rangeMin !== null) {
if ($operand->getMax() !== null) {
/** @var int|float $min */
$min = $rangeMin - $operand->getMax();
} else {
/** @var int|float $min */
$min = $rangeMin - $operand->getMin();
}
} else {
Expand All @@ -5442,9 +5453,11 @@ private function integerRangeMath(Type $range, Expr $node, Type $operand): Type
$max = null;
} elseif ($rangeMax !== null) {
if ($rangeMin !== null && $operand->getMin() === null) {
/** @var int|float $min */
$min = $rangeMin - $operand->getMax();
$max = null;
} elseif ($operand->getMin() !== null) {
/** @var int|float $max */
$max = $rangeMax - $operand->getMin();
} else {
$max = null;
Expand All @@ -5460,10 +5473,16 @@ private function integerRangeMath(Type $range, Expr $node, Type $operand): Type
}
} elseif ($node instanceof Node\Expr\BinaryOp\Mul || $node instanceof Node\Expr\AssignOp\Mul) {
if ($operand instanceof ConstantIntegerType) {
/** @var int|float|null $min */
$min = $rangeMin !== null ? $rangeMin * $operand->getValue() : null;

/** @var int|float|null $max */
$max = $rangeMax !== null ? $rangeMax * $operand->getValue() : null;
} else {
/** @var int|float|null $min */
$min = $rangeMin !== null && $operand->getMin() !== null ? $rangeMin * $operand->getMin() : null;

/** @var int|float|null $max */
$max = $rangeMax !== null && $operand->getMax() !== null ? $rangeMax * $operand->getMax() : null;
}

Expand Down Expand Up @@ -5527,6 +5546,13 @@ private function integerRangeMath(Type $range, Expr $node, Type $operand): Type
}
}

if (is_float($min)) {
$min = null;
}
if (is_float($max)) {
$max = null;
}

return IntegerRangeType::fromInterval($min, $max);
}

Expand Down
6 changes: 6 additions & 0 deletions tests/PHPStan/Analyser/AnalyserIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,12 @@ public function testBug6300(): void
$this->assertSame(24, $errors[1]->getLine());
}

public function testBug6466(): void
{
$errors = $this->runAnalyse(__DIR__ . '/data/bug-6466.php');
$this->assertNoErrors($errors);
}

public function testBug6253(): void
{
$errors = $this->runAnalyse(
Expand Down
12 changes: 12 additions & 0 deletions tests/PHPStan/Analyser/data/bug-6466.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

namespace Bug6466;

class HelloWorld
{
public function sayHello(\DateTimeImmutable $date): void
{
for ($i = 1; $i <= 1e18; $i *= 10) {
}
}
}

0 comments on commit f1734dc

Please sign in to comment.