Repository navigation
Commit 48d75ab
Drop the foreach value alias on dynamic-variable writes to the iteratee
The value-variable alias projected onto $array[$key] is only sound while the
loop body cannot mutate the iteratee at a foreign key. foreachAliasDesyncingTarget
flagged such writes only when their target base was a statically named Variable
equal to the iteratee, so a dynamic-variable base slipped through: $$name[$key + 1]
(with $name = 'data') resolves to the iteratee at runtime and desyncs the live
element from the snapshot value variable, yet the alias survived and projected a
narrowed int onto $data[$key] whose sound type is int|string.
Make the detector conservatively complete - the alias is a pure precision
optimization, so any write target that cannot be proven to be exactly the
iteratee at the current key (or a distinctly named non-iteratee location) drops
it. A dim fetch whose base is a Variable with a non-string (Expr) name - a
variable-variable ($$name[...]) or a curly dynamic variable (${'data'}[...]) -
now desyncs, as does a bare dynamic-variable write ($$name = ...) that may target
the key or value variable, and a dynamic global ($$name). The #7508 same-key
sub-offset write ($array[$key][0] = ...) stays kept.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CGhnJQpUWRRpg6H5LuWJkA1 parent 63d438b commit 48d75ab
2 files changed
Lines changed: 96 additions & 10 deletions
File tree
- src/Analyser/StmtHandler
- tests/PHPStan/Analyser/nsrt
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
695 | 695 | | |
696 | 696 | | |
697 | 697 | | |
698 | | - | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
| 701 | + | |
| 702 | + | |
| 703 | + | |
699 | 704 | | |
700 | 705 | | |
701 | 706 | | |
| |||
741 | 746 | | |
742 | 747 | | |
743 | 748 | | |
| 749 | + | |
| 750 | + | |
| 751 | + | |
| 752 | + | |
| 753 | + | |
| 754 | + | |
| 755 | + | |
| 756 | + | |
| 757 | + | |
744 | 758 | | |
745 | 759 | | |
746 | 760 | | |
| |||
756 | 770 | | |
757 | 771 | | |
758 | 772 | | |
759 | | - | |
760 | | - | |
761 | | - | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
762 | 785 | | |
763 | 786 | | |
764 | | - | |
765 | | - | |
766 | | - | |
767 | | - | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
768 | 795 | | |
769 | 796 | | |
770 | 797 | | |
771 | | - | |
772 | | - | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
773 | 807 | | |
774 | 808 | | |
775 | 809 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
45 | 97 | | |
46 | 98 | | |
47 | 99 | | |
| |||
0 commit comments