Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions src/Analyser/NodeScopeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -1517,8 +1517,16 @@ private function processStmtNode(
}

$breakExitPoints = $finalScopeResult->getExitPointsByType(Break_::class);
foreach ($breakExitPoints as $breakExitPoint) {
$finalScope = $finalScope->mergeWith($breakExitPoint->getScope());
if ($alwaysIterates && count($breakExitPoints) > 0) {
$breakScope = null;
foreach ($breakExitPoints as $breakExitPoint) {
$breakScope = $breakScope === null ? $breakExitPoint->getScope() : $breakScope->mergeWith($breakExitPoint->getScope());
}
$finalScope = $breakScope;
} else {
foreach ($breakExitPoints as $breakExitPoint) {
$finalScope = $finalScope->mergeWith($breakExitPoint->getScope());
}
}

$isIterableAtLeastOnce = $beforeCondBooleanType->isTrue()->yes();
Expand Down
69 changes: 69 additions & 0 deletions tests/PHPStan/Rules/Variables/DefinedVariableRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1257,4 +1257,73 @@ public function testBug12944(): void
$this->analyse([__DIR__ . '/data/bug-12944.php'], []);
}

public function testBug9023(): void
{
$this->cliArgumentsVariablesRegistered = true;
$this->polluteScopeWithLoopInitialAssignments = false;
$this->checkMaybeUndefinedVariables = true;
$this->polluteScopeWithAlwaysIterableForeach = true;

$this->analyse([__DIR__ . '/data/bug-9023.php'], []);
}

public function testBug11984(): void
{
$this->cliArgumentsVariablesRegistered = true;
$this->polluteScopeWithLoopInitialAssignments = false;
$this->checkMaybeUndefinedVariables = true;
$this->polluteScopeWithAlwaysIterableForeach = true;

$this->analyse([__DIR__ . '/data/bug-11984.php'], []);
}

public function testBug11545(): void
{
$this->cliArgumentsVariablesRegistered = true;
$this->polluteScopeWithLoopInitialAssignments = false;
$this->checkMaybeUndefinedVariables = true;
$this->polluteScopeWithAlwaysIterableForeach = true;

$this->analyse([__DIR__ . '/data/bug-11545.php'], [
[
'Variable $result might not be defined.',
24,
],
[
'Variable $result might not be defined.',
36,
],
]);
}

public function testBug10245(): void
{
$this->cliArgumentsVariablesRegistered = true;
$this->polluteScopeWithLoopInitialAssignments = false;
$this->checkMaybeUndefinedVariables = true;
$this->polluteScopeWithAlwaysIterableForeach = true;

$this->analyse([__DIR__ . '/data/bug-10245.php'], []);
}

public function testBug5919(): void
{
$this->cliArgumentsVariablesRegistered = true;
$this->polluteScopeWithLoopInitialAssignments = false;
$this->checkMaybeUndefinedVariables = true;
$this->polluteScopeWithAlwaysIterableForeach = true;

$this->analyse([__DIR__ . '/data/bug-5919.php'], []);
}

public function testBug5477(): void
{
$this->cliArgumentsVariablesRegistered = true;
$this->polluteScopeWithLoopInitialAssignments = false;
$this->checkMaybeUndefinedVariables = true;
$this->polluteScopeWithAlwaysIterableForeach = true;

$this->analyse([__DIR__ . '/data/bug-5477.php'], []);
}

}
36 changes: 36 additions & 0 deletions tests/PHPStan/Rules/Variables/data/bug-10245.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php declare(strict_types = 1); // lint >= 8.0

namespace Bug10245;

/**
* @throws \Exception
*/
function produceInt(): int
{
return 1;
}

function testTryCatchInWhileTrue(): void
{
while (true) {
try {
$a = produceInt();
break;
} catch (\Throwable) {}
}

echo $a;
}

function testIfBreakInWhileTrue(int $max): void
{
$i = 0;
while (true) {
if ($i > $max) {
$result = 'done';
break;
}
++$i;
}
print $result;
}
45 changes: 45 additions & 0 deletions tests/PHPStan/Rules/Variables/data/bug-11545.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php declare(strict_types = 1);

namespace Bug11545;

function foo(int $max): void {
$i = 0;
while (true) {
if ($i > $max) {
$result = 'done';
break;
}
++$i;
}
print $result;
}

function foo_for(int $max): void {
for ($i = 0;; ++$i) {
if ($i > $max) {
$result = 'done';
break;
}
}
print $result;
}

function foo_do_while(int $max): void {
$i = 0;
do {
if ($i > $max) {
$result = 'done';
break;
}
++$i;
} while (true);
print $result;
}

function bar(int $max): void {
while (true) {
$result = 'done';
break;
}
print $result;
}
31 changes: 31 additions & 0 deletions tests/PHPStan/Rules/Variables/data/bug-11984.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php declare(strict_types = 1);

namespace Bug11984;

class Foo
{
/**
* @return array<string, mixed>
*/
public function loadFromFile(): array
{
return ['x' => 1];
}

/**
* @return array<string, mixed>
*/
public function test(): array
{
while (true) {
try {
$data = $this->loadFromFile();

break;
} catch (\Exception $ex) {
}
}

return $data;
}
}
16 changes: 16 additions & 0 deletions tests/PHPStan/Rules/Variables/data/bug-5477.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php declare(strict_types = 1);

namespace Bug5477;

function foo(): int {
while (true) {
try {
$transaction = 1;
break;
} catch (\Throwable $e) {
continue;
}
}

return $transaction;
}
50 changes: 50 additions & 0 deletions tests/PHPStan/Rules/Variables/data/bug-5919.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

namespace Bug5919;

/**
* @return mixed[]
*/
function queryApi(): array
{
return [5];
}

function isTimeout(): bool
{
return true;
}

function testSimple(): void
{
while (true) {
try {
$s = queryApi();
break;
} catch (\Exception $e) {
if (false) {
throw $e;
}
}
}

var_dump(count($s));
}

function testWithIsTimeout(): void
{
while (true) {
try {
$s = queryApi();
break;
} catch (\Exception $e) {
if (isTimeout()) {
throw $e;
}
}
}

var_dump(count($s));
}
29 changes: 29 additions & 0 deletions tests/PHPStan/Rules/Variables/data/bug-9023.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php declare(strict_types = 1);

namespace Bug9023;

use Exception;

function unreliableFunc(): string
{
if (random_int(1, 5) === 1) {
return 'something';
} else {
throw new Exception('Just demonstrating');
}
}

function testWhileTrueBreakWithTryCatch(): void
{
while (true) {
try {
$defined = unreliableFunc();
break;
} catch (Exception $e) {
sleep(10);
continue;
}
}

echo $defined;
}
Loading