@@ -809,7 +809,7 @@ private function processStmtNode(
809809 $ finalScope ,
810810 $ finalScopeResult ->hasYield () || $ condResult ->hasYield (),
811811 $ isIterableAtLeastOnce ->yes () && $ finalScopeResult ->isAlwaysTerminating (),
812- []
812+ $ finalScopeResult -> getExitPointsForOuterLoop ()
813813 );
814814 } elseif ($ stmt instanceof While_) {
815815 $ condResult = $ this ->processExprNode ($ stmt ->cond , $ scope , static function (): void {
@@ -875,7 +875,7 @@ private function processStmtNode(
875875 $ finalScope ,
876876 $ finalScopeResult ->hasYield () || $ condResult ->hasYield (),
877877 $ isAlwaysTerminating ,
878- []
878+ $ finalScopeResult -> getExitPointsForOuterLoop ()
879879 );
880880 } elseif ($ stmt instanceof Do_) {
881881 $ finalScope = null ;
@@ -940,7 +940,7 @@ private function processStmtNode(
940940 $ finalScope ,
941941 $ bodyScopeResult ->hasYield () || $ hasYield ,
942942 $ alwaysTerminating ,
943- []
943+ $ bodyScopeResult -> getExitPointsForOuterLoop ()
944944 );
945945 } elseif ($ stmt instanceof For_) {
946946 $ initScope = $ scope ;
@@ -1014,7 +1014,7 @@ private function processStmtNode(
10141014 $ finalScope ,
10151015 $ finalScopeResult ->hasYield () || $ hasYield ,
10161016 false /* $finalScopeResult->isAlwaysTerminating() && $isAlwaysIterable*/ ,
1017- []
1017+ $ finalScopeResult -> getExitPointsForOuterLoop ()
10181018 );
10191019 } elseif ($ stmt instanceof Switch_) {
10201020 $ condResult = $ this ->processExprNode ($ stmt ->cond , $ scope , $ nodeCallback , ExpressionContext::createDeep ());
@@ -1025,6 +1025,7 @@ private function processStmtNode(
10251025 $ hasDefaultCase = false ;
10261026 $ alwaysTerminating = true ;
10271027 $ hasYield = $ condResult ->hasYield ();
1028+ $ exitPointsForOuterLoop = [];
10281029 foreach ($ stmt ->cases as $ caseNode ) {
10291030 if ($ caseNode ->cond !== null ) {
10301031 $ condExpr = new BinaryOp \Equal ($ stmt ->cond , $ caseNode ->cond );
@@ -1047,6 +1048,7 @@ private function processStmtNode(
10471048 foreach ($ branchScopeResult ->getExitPointsByType (Continue_::class) as $ continueExitPoint ) {
10481049 $ finalScope = $ continueExitPoint ->getScope ()->mergeWith ($ finalScope );
10491050 }
1051+ $ exitPointsForOuterLoop = array_merge ($ exitPointsForOuterLoop , $ branchFinalScopeResult ->getExitPointsForOuterLoop ());
10501052 if ($ branchScopeResult ->isAlwaysTerminating ()) {
10511053 $ alwaysTerminating = $ alwaysTerminating && $ branchFinalScopeResult ->isAlwaysTerminating ();
10521054 $ prevScope = null ;
@@ -1074,7 +1076,7 @@ private function processStmtNode(
10741076 $ finalScope = $ scope ->mergeWith ($ finalScope );
10751077 }
10761078
1077- return new StatementResult ($ finalScope , $ hasYield , $ alwaysTerminating , [] );
1079+ return new StatementResult ($ finalScope , $ hasYield , $ alwaysTerminating , $ exitPointsForOuterLoop );
10781080 } elseif ($ stmt instanceof TryCatch) {
10791081 $ branchScopeResult = $ this ->processStmtNodes ($ stmt , $ stmt ->stmts , $ scope , $ nodeCallback );
10801082 $ branchScope = $ branchScopeResult ->getScope ();
0 commit comments