Skip to content

Commit b12745b

Browse files
phpstan-botVincentLangletclaude
authored
Fix phpstan/phpstan#14063: Readonly property modification through clone() is not reported outside allowed scope (#5432)
Co-authored-by: VincentLanglet <9052536+VincentLanglet@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 7092778 commit b12745b

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

tests/PHPStan/Rules/Properties/AccessPropertiesInAssignRuleTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,25 @@ public function testBug13123(): void
207207
$this->analyse([__DIR__ . '/data/bug-13123.php'], []);
208208
}
209209

210+
#[RequiresPhp('>= 8.5')]
211+
public function testBug14063(): void
212+
{
213+
$this->analyse([__DIR__ . '/data/bug-14063.php'], [
214+
[
215+
'Assign to protected(set) property Bug14063\Obj::$value.',
216+
31,
217+
],
218+
[
219+
'Assign to protected(set) property Bug14063\Obj::$value.',
220+
34,
221+
],
222+
[
223+
'Assign to protected(set) property Bug14063\Base::$value.',
224+
38,
225+
],
226+
]);
227+
}
228+
210229
#[RequiresPhp('>= 8.5')]
211230
public function testCloneWith(): void
212231
{
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php // lint >= 8.5
2+
3+
declare(strict_types = 1);
4+
5+
namespace Bug14063;
6+
7+
final readonly class Obj
8+
{
9+
public function __construct(public string $value) {}
10+
11+
public function withValue(string $newValue): self
12+
{
13+
return clone($this, ['value' => $newValue]);
14+
}
15+
}
16+
17+
readonly class Base
18+
{
19+
public function __construct(public string $value) {}
20+
}
21+
22+
readonly class Child extends Base
23+
{
24+
public function withValue(string $newValue): self
25+
{
26+
return clone($this, ['value' => $newValue]);
27+
}
28+
}
29+
30+
$obj = new Obj('val');
31+
$newObj = clone($obj, ['value' => 'newVal']);
32+
33+
function test(Obj $obj): void {
34+
clone($obj, ['value' => 'newVal']);
35+
}
36+
37+
function testBase(Base $base): void {
38+
clone($base, ['value' => 'newVal']);
39+
}

0 commit comments

Comments
 (0)