Skip to content

Commit 225e1cd

Browse files
phpstan-botclaude
andcommitted
Add regression tests for issues also fixed by the finally exit point change
Closes phpstan/phpstan#12215 Closes phpstan/phpstan#11906 Closes phpstan/phpstan#7665 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 5bc1fec commit 225e1cd

4 files changed

Lines changed: 111 additions & 0 deletions

File tree

tests/PHPStan/Rules/Exceptions/OverwrittenExitPointByFinallyRuleTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,21 @@ public function testBug6670(): void
4343
$this->analyse([__DIR__ . '/data/bug-6670.php'], []);
4444
}
4545

46+
public function testBug12215(): void
47+
{
48+
$this->analyse([__DIR__ . '/data/bug-12215.php'], []);
49+
}
50+
51+
public function testBug11906(): void
52+
{
53+
$this->analyse([__DIR__ . '/data/bug-11906.php'], []);
54+
}
55+
56+
public function testBug7665(): void
57+
{
58+
$this->analyse([__DIR__ . '/data/bug-7665.php'], []);
59+
}
60+
4661
public function testBug5627(): void
4762
{
4863
$this->analyse([__DIR__ . '/data/bug-5627.php'], [
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug11906;
4+
5+
function func(): void {
6+
try {
7+
throw new \LogicException('test');
8+
} catch (\LogicException $e) {
9+
// This catch-block should cause line 7 to not be treated as an exit point
10+
} finally {
11+
if (getenv('FOO')) {
12+
return;
13+
}
14+
}
15+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug12215;
4+
5+
abstract class Spinlock
6+
{
7+
private float $expireTimeout;
8+
9+
private ?float $acquireTs = null;
10+
11+
private ?string $token = null;
12+
13+
public function __construct(float $expireTimeout = \PHP_INT_MAX)
14+
{
15+
$this->expireTimeout = $expireTimeout;
16+
17+
// acquire lock
18+
$this->acquireTs = microtime(true);
19+
$this->token = random_bytes(64);
20+
}
21+
22+
protected function release(string $key): bool
23+
{
24+
try {
25+
return $this->releaseWithToken($key, $this->token);
26+
} finally {
27+
$this->token = null;
28+
29+
$elapsedTime = microtime(true) - $this->acquireTs;
30+
if ($elapsedTime >= $this->expireTimeout) {
31+
throw new \Exception('Execution outside lock exception');
32+
}
33+
}
34+
}
35+
36+
protected function release2(string $key): bool
37+
{
38+
try {
39+
return $this->releaseWithToken($key, $this->token);
40+
} finally {
41+
try {
42+
$elapsedTime = microtime(true) - $this->acquireTs;
43+
if ($elapsedTime >= $this->expireTimeout) {
44+
throw new \Exception('Execution outside lock exception');
45+
}
46+
} finally {
47+
$this->token = null;
48+
}
49+
}
50+
}
51+
52+
abstract protected function releaseWithToken(string $key, string $token): bool;
53+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug7665;
4+
5+
class HelloWorld
6+
{
7+
public function doStuff(): string
8+
{
9+
try {
10+
if(rand(0,1) === 1) {
11+
throw new \RuntimeException('Bad luck');
12+
}
13+
14+
15+
return 'yay';
16+
// other stuff
17+
} catch(\Throwable $e) {
18+
if (rand(0,1) === 1) {
19+
exit(1);
20+
}
21+
// do some stuff to reset
22+
} finally {
23+
if(rand(0,1) === 1) {
24+
exit(1);
25+
}
26+
}
27+
}
28+
}

0 commit comments

Comments
 (0)