From fca23a9a1238156873d310f1a066a55a55857ee9 Mon Sep 17 00:00:00 2001 From: Claude Pache Date: Wed, 12 Nov 2025 21:44:27 +0100 Subject: [PATCH 1/2] Do not report do-while-false loops that are interrupted by a break statement --- .../DoWhileLoopConstantConditionRule.php | 7 +++++ .../DoWhileLoopConstantConditionRuleTest.php | 12 ++++--- .../Rules/Comparison/data/do-while-loop.php | 31 ++++++++++++++++++- 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/Rules/Comparison/DoWhileLoopConstantConditionRule.php b/src/Rules/Comparison/DoWhileLoopConstantConditionRule.php index 5c5e193222..986b27529b 100644 --- a/src/Rules/Comparison/DoWhileLoopConstantConditionRule.php +++ b/src/Rules/Comparison/DoWhileLoopConstantConditionRule.php @@ -65,6 +65,13 @@ public function processNode(Node $node, Scope $scope): array return []; } } + } else { + foreach ($node->getExitPoints() as $exitPoint) { + $statement = $exitPoint->getStatement(); + if ($statement instanceof Break_) { + return []; + } + } } $addTip = function (RuleErrorBuilder $ruleErrorBuilder) use ($scope, $node): RuleErrorBuilder { diff --git a/tests/PHPStan/Rules/Comparison/DoWhileLoopConstantConditionRuleTest.php b/tests/PHPStan/Rules/Comparison/DoWhileLoopConstantConditionRuleTest.php index f83f2cf1b0..c67709a560 100644 --- a/tests/PHPStan/Rules/Comparison/DoWhileLoopConstantConditionRuleTest.php +++ b/tests/PHPStan/Rules/Comparison/DoWhileLoopConstantConditionRuleTest.php @@ -43,10 +43,6 @@ public function testRule(): void 'Do-while loop condition is always false.', 46, ], - [ - 'Do-while loop condition is always false.', - 55, - ], [ 'Do-while loop condition is always true.', 64, @@ -55,6 +51,14 @@ public function testRule(): void 'Do-while loop condition is always false.', 73, ], + [ + 'Do-while loop condition is always false.', + 105, + ], + [ + 'Do-while loop condition is always false.', + 115, + ], ]); } diff --git a/tests/PHPStan/Rules/Comparison/data/do-while-loop.php b/tests/PHPStan/Rules/Comparison/data/do-while-loop.php index 02eb303d34..ac85c1f21a 100644 --- a/tests/PHPStan/Rules/Comparison/data/do-while-loop.php +++ b/tests/PHPStan/Rules/Comparison/data/do-while-loop.php @@ -52,7 +52,7 @@ public function doBar3() if (rand(0, 1)) { break; } - } while (false); // report + } while (false); // do not report } public function doFoo4() @@ -95,4 +95,33 @@ public function doFoo6(array $a) } } + public function doFoo8(array $a) + { + foreach ($a as $v) { + do { + if (rand(0, 1)) { + continue 2; + } + } while (false); // report + } + } + + public function doFoo9(array $a) + { + do { + foreach ($a as $v) { + break; + } + } while (false); // report + } + + public function doFoo10(array $a) + { + do { + foreach ($a as $v) { + break 2; + } + } while (false); // do not report + } + } From 97e48d35a92377d9cd0b30776208ed219595d888 Mon Sep 17 00:00:00 2001 From: Claude Pache Date: Fri, 14 Nov 2025 14:32:49 +0100 Subject: [PATCH 2/2] simplify logic for the do-while(true) case; additional tests --- .../DoWhileLoopConstantConditionRule.php | 13 +-------- .../DoWhileLoopConstantConditionRuleTest.php | 8 ++++++ .../Rules/Comparison/data/do-while-loop.php | 28 +++++++++++++++++++ 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/src/Rules/Comparison/DoWhileLoopConstantConditionRule.php b/src/Rules/Comparison/DoWhileLoopConstantConditionRule.php index 986b27529b..7087fbd006 100644 --- a/src/Rules/Comparison/DoWhileLoopConstantConditionRule.php +++ b/src/Rules/Comparison/DoWhileLoopConstantConditionRule.php @@ -44,24 +44,13 @@ public function processNode(Node $node, Scope $scope): array if ($exprType->getValue()) { foreach ($node->getExitPoints() as $exitPoint) { $statement = $exitPoint->getStatement(); - if ($statement instanceof Break_) { - return []; - } if (!$statement instanceof Continue_) { return []; } - if ($statement->num === null) { - continue; - } if (!$statement->num instanceof Int_) { continue; } - $value = $statement->num->value; - if ($value === 1) { - continue; - } - - if ($value > 1) { + if ($statement->num->value > 1) { return []; } } diff --git a/tests/PHPStan/Rules/Comparison/DoWhileLoopConstantConditionRuleTest.php b/tests/PHPStan/Rules/Comparison/DoWhileLoopConstantConditionRuleTest.php index c67709a560..519413d54e 100644 --- a/tests/PHPStan/Rules/Comparison/DoWhileLoopConstantConditionRuleTest.php +++ b/tests/PHPStan/Rules/Comparison/DoWhileLoopConstantConditionRuleTest.php @@ -59,6 +59,14 @@ public function testRule(): void 'Do-while loop condition is always false.', 115, ], + [ + 'Do-while loop condition is always false.', + 138, + ], + [ + 'Do-while loop condition is always false.', + 152, + ], ]); } diff --git a/tests/PHPStan/Rules/Comparison/data/do-while-loop.php b/tests/PHPStan/Rules/Comparison/data/do-while-loop.php index ac85c1f21a..a2d03bb039 100644 --- a/tests/PHPStan/Rules/Comparison/data/do-while-loop.php +++ b/tests/PHPStan/Rules/Comparison/data/do-while-loop.php @@ -124,4 +124,32 @@ public function doFoo10(array $a) } while (false); // do not report } + public function doFoo11(array $a) + { + do { + throw new \Exception; + } while (true); // do not report + } + + public function doFoo12(array $a) + { + do { + throw new \Exception; + } while (false); // report + } + + public function doFoo13(array $a) + { + do { + exit; + } while (true); // do not report + } + + public function doFoo12(array $a) + { + do { + exit; + } while (false); // report + } + }