Skip to content

Commit

Permalink
modulo 1 is always zero
Browse files Browse the repository at this point in the history
  • Loading branch information
staabm committed Feb 6, 2022
1 parent 5348490 commit 39e5e0c
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 4 deletions.
20 changes: 16 additions & 4 deletions src/Analyser/MutatingScope.php
Expand Up @@ -1051,12 +1051,24 @@ private function resolveType(Expr $node): Type
} else {
$right = $node->right;
}
$rightType = $this->getType($right);

$integerType = $rightType->toInteger();
if (
$node instanceof Node\Expr\BinaryOp\Mod
|| $node instanceof Node\Expr\AssignOp\Mod
) {
if ($integerType instanceof ConstantIntegerType && $integerType->getValue() === 1) {
return new ConstantIntegerType(0);
}
}

$rightScalarTypes = TypeUtils::getConstantScalars($rightType->toNumber());
foreach ($rightScalarTypes as $scalarType) {

$rightTypes = TypeUtils::getConstantScalars($this->getType($right)->toNumber());
foreach ($rightTypes as $rightType) {
if (
$rightType->getValue() === 0
|| $rightType->getValue() === 0.0
$scalarType->getValue() === 0
|| $scalarType->getValue() === 0.0
) {
return new ErrorType();
}
Expand Down
5 changes: 5 additions & 0 deletions tests/PHPStan/Analyser/data/div-by-zero.php
Expand Up @@ -17,7 +17,12 @@ public function doFoo(int $range1, int $range2, int $int): void
assertType('(float|int)', 5 / $range2);
assertType('(float|int)', $range1 / $range2);
assertType('(float|int)', 5 / $int);

assertType('*ERROR*', 5 / 0);
assertType('*ERROR*', 5 / '0');
assertType('*ERROR*', 5 / 0.0);
assertType('*ERROR*', 5 / false);
assertType('*ERROR*', 5 / null);
}

}
28 changes: 28 additions & 0 deletions tests/PHPStan/Analyser/data/modulo-operator.php
Expand Up @@ -45,4 +45,32 @@ function doBar(int $i, int $j, $p, $range, $zeroOrMore, $intConst, $unionRange,

assertType('int', $j % $i);
}

function moduleOne(int $i, float $f) {
assertType('0', true % '1');
assertType('0', false % '1');
assertType('0', null % '1');
assertType('0', -1 % '1');
assertType('0', 0 % '1');
assertType('0', 1 % '1');
assertType('0', '1' % '1');
assertType('0', 1.24 % '1');

assertType('0', $i % 1.0);
assertType('0', $f % 1.0);

assertType('0', $i % '1.0');
assertType('0', $f % '1.0');

assertType('0', $i % '1');
assertType('0', $f % '1');

assertType('0', $i % true);
assertType('0', $f % true);

$i %= '1';
$f %= '1';
assertType('0', $i);
assertType('0', $f);
}
}

0 comments on commit 39e5e0c

Please sign in to comment.