Skip to content

Commit

Permalink
Merge pull request #7992 from AndrolGenhald/bugfix/7973
Browse files Browse the repository at this point in the history
Fix class const issue when using floats declared in future consts (fixes #7973).
  • Loading branch information
orklah committed May 21, 2022
2 parents 9908871 + 80e94da commit b46fb14
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 4 deletions.
Expand Up @@ -47,6 +47,7 @@
use function array_diff_key;
use function array_values;
use function count;
use function get_class;
use function is_int;
use function is_numeric;
use function max;
Expand Down Expand Up @@ -309,15 +310,30 @@ private static function analyzeOperands(
bool &$has_string_increment,
Union &$result_type = null
): ?Union {
if ($left_type_part instanceof TLiteralInt
&& $right_type_part instanceof TLiteralInt
if (($left_type_part instanceof TLiteralInt || $left_type_part instanceof TLiteralFloat)
&& ($right_type_part instanceof TLiteralInt || $right_type_part instanceof TLiteralFloat)
&& (
//we don't try to do arithmetics on variables in loops
$context === null
|| $context->inside_loop === false
|| (!$left instanceof PhpParser\Node\Expr\Variable && !$right instanceof PhpParser\Node\Expr\Variable)
)
) {
// get_class is fine here because both classes are final.
if ($statements_source !== null
&& $config->strict_binary_operands
&& get_class($left_type_part) !== get_class($right_type_part)
) {
IssueBuffer::maybeAdd(
new InvalidOperand(
'Cannot process numeric types together in strict operands mode, '.
'please cast explicitly',
new CodeLocation($statements_source, $parent)
),
$statements_source->getSuppressedIssues()
);
}

// time for some arithmetic!
$calculated_type = self::arithmeticOperation(
$parent,
Expand Down
Expand Up @@ -712,7 +712,6 @@ public static function analyzeAssignment(
"{$class_storage->name}::{$const->name->name}"
),
$const_storage->suppressed_issues,
true
);
}
}
Expand Down
27 changes: 26 additions & 1 deletion tests/BinaryOperationTest.php
Expand Up @@ -191,7 +191,7 @@ function returnsABool(): bool {
$this->analyzeFile('somefile.php', new Context());
}

public function testDifferingNumericTypesAdditionInStrictMode(): void
public function testDifferingNumericLiteralTypesAdditionInStrictMode(): void
{
$config = Config::getInstance();
$config->strict_binary_operands = true;
Expand All @@ -208,6 +208,25 @@ public function testDifferingNumericTypesAdditionInStrictMode(): void
$this->analyzeFile('somefile.php', new Context());
}

public function testDifferingNumericTypesAdditionInStrictMode(): void
{
$config = Config::getInstance();
$config->strict_binary_operands = true;

$this->addFile(
'somefile.php',
'<?php
/** @var float */
$b = 4.1;
$a = 5 + $b;'
);

$this->expectException(CodeException::class);
$this->expectExceptionMessage('InvalidOperand');

$this->analyzeFile('somefile.php', new Context());
}

public function testConcatenationWithNumberInStrictMode(): void
{
$config = Config::getInstance();
Expand Down Expand Up @@ -852,6 +871,12 @@ function toPositiveInt(int $i): int
return 1;
}',
],
'calculateLiteralResultForFloats' => [
'code' => '<?php
$foo = 1.0 + 2.0;
',
'assertions' => ['$foo===' => 'float(3)'],
],
];
}

Expand Down
9 changes: 9 additions & 0 deletions tests/ConstantTest.php
Expand Up @@ -1419,6 +1419,15 @@ interface Foo
interface Bar extends Foo {}
',
],
'classConstsUsingFutureFloatDeclarationWithMultipleLevels' => [
'code' => '<?php
class Foo {
public const BAZ = self::BAR + 1.0;
public const BAR = self::FOO + 1.0;
public const FOO = 1.0;
}
',
],
];
}

Expand Down

0 comments on commit b46fb14

Please sign in to comment.