Skip to content

Fix phpstan/phpstan#6670: Return in finally does not always overwrite return in try-catch#5163

Merged
ondrejmirtes merged 2 commits intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-sunfnbn
Mar 13, 2026
Merged

Fix phpstan/phpstan#6670: Return in finally does not always overwrite return in try-catch#5163
ondrejmirtes merged 2 commits intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-sunfnbn

Conversation

@phpstan-bot
Copy link
Collaborator

@phpstan-bot phpstan-bot commented Mar 9, 2026

Summary

PHPStan incorrectly reported "This return is overwritten by a different one in the finally block below" when the overwriting return was inside a catch block within the finally block. Since the catch only executes if an exception is thrown, the return doesn't always overwrite the one in the try block.

Changes

  • Added $finallyResult->isAlwaysTerminating() check in src/Analyser/NodeScopeResolver.php (line ~2031) so the FinallyExitPointsNode is only emitted when the finally block unconditionally terminates via an exit point
  • Added regression test in tests/PHPStan/Rules/Exceptions/data/bug-6670.php
  • Added test method testBug6670 in tests/PHPStan/Rules/Exceptions/OverwrittenExitPointByFinallyRuleTest.php

Root cause

The condition for emitting FinallyExitPointsNode only checked count($finallyResult->getExitPoints()) > 0, which is true whenever there's any exit point anywhere in the finally block — even inside a catch. But a return in a catch doesn't always execute; it only runs when an exception is caught. The fix adds $finallyResult->isAlwaysTerminating() to ensure the warning is only shown when the finally block always terminates, meaning every code path through the finally hits an exit point.

Test

The regression test reproduces the exact scenario from the issue: a try block with a return, and a finally block containing a try/catch where only the catch has a return. The test expects no errors, since the finally block's return is conditional.

Fixes phpstan/phpstan#6670

Closes phpstan/phpstan#12215
Closes phpstan/phpstan#11906
Closes phpstan/phpstan#7665

@VincentLanglet VincentLanglet requested a review from staabm March 9, 2026 22:07
@ondrejmirtes
Copy link
Member

Needs 4 more regression tests.

1 similar comment
@ondrejmirtes
Copy link
Member

Needs 4 more regression tests.

…n catch

- Only emit FinallyExitPointsNode when the finally block always terminates,
  not just when it has any exit points
- A return inside a catch within finally doesn't always execute, so it
  shouldn't be reported as unconditionally overwriting the try-catch return
- New regression test in tests/PHPStan/Rules/Exceptions/data/bug-6670.php

Closes phpstan/phpstan#6670
@ondrejmirtes ondrejmirtes force-pushed the create-pull-request/patch-sunfnbn branch from 2d7d93d to 5bc1fec Compare March 12, 2026 17:03
Copy link
Member

@ondrejmirtes ondrejmirtes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add regression tests for fixed issues based on https://github.com/phpstan/phpstan-src/actions/runs/22862533139 and add “closes X” to the PR description for them.

@phpstan-bot
Copy link
Collaborator Author

Both background tasks have completed. As noted earlier, make phpstan passed cleanly and the one test failure (RawErrorFormatterTest) is pre-existing and unrelated to our changes. All regression tests for #6670, #12215, #11906, and #7665 pass.

@phpstan-bot
Copy link
Collaborator Author

The review from VincentLanglet is an APPROVED review with no requested changes. There's nothing to address - the PR is already in good shape.

Looking at the history:

  • ondrejmirtes previously requested regression tests, which were added (bug-6670, bug-12215, bug-11906, bug-7665)
  • staabm approved
  • VincentLanglet approved (twice)
  • The CI passed (with only a pre-existing unrelated test failure)

The PR is ready for merge. No further action needed.

Copy link
Contributor

@staabm staabm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked all tests are failling without the fix. lgtm.

@phpstan-bot
Copy link
Collaborator Author

The review from staabm is an APPROVED review with a positive comment ("I checked all tests are failling without the fix. lgtm."). There are no requested changes to address.

The PR has now been approved by staabm and VincentLanglet (twice), with all previously requested changes (regression tests from ondrejmirtes) already addressed. No further action is needed.

@ondrejmirtes ondrejmirtes merged commit fed13e0 into phpstan:2.1.x Mar 13, 2026
645 of 653 checks passed
@ondrejmirtes ondrejmirtes deleted the create-pull-request/patch-sunfnbn branch March 13, 2026 09:13
@phpstan-bot
Copy link
Collaborator Author

I processed this review but have nothing to report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants