Commit d657b6c
committed
sema: support reinterpreting extern/packed unions at comptime via field access
My previous change for reading / writing to unions at comptime did not handle
union field read/writes correctly in all cases. Previously, if a field was
written to a union, it would overwrite the entire value. This is problematic
when a field of a larger size is subsequently read, because the value would not
be long enough, causing a panic.
Additionally, the writing behaviour itself was incorrect. Writing to a field of
a packed or extern union should only overwrite the bits corresponding to that
field, allowing for memory reintepretation via field writes / reads.
I addressed these problems as follows:
Add the concept of a "backing type" for extern / packed unions
(`Type.unionBackingType`). For extern unions, this is a `u8` array, for packed
unions it's an integer matching the `bitSize` of the union. Whenever union
memory is read at comptime, it's read as this type.
When union memory is written at comptime, the tag may still be known. If so, the
memory is written using the tagged type. If the tag is unknown (because this
union had previously been read from memory), it's simply written back out as the
backing type.
I added `write_packed` to the `reinterpret` field of
`ComptimePtrMutationKit`. This causes writes of the operand to be packed - which
is necessary when writing to a field of a packed union. Without this, writing a
value to a `u1` field would overwrite the entire byte it occupied.
The final case to address was reading a different (potentially larger) field
from a union when it was written with a known tag. To handle this, a new kind of
bitcast was introduced (`bitCastUnionFieldVal`) which supports reading a larger
field by using a backing buffer that has the unwritten bits set to
undefined. The reason to support this (vs always just writing the union as it's
backing type), is that no reads to larger fields ever occur at comptime, it
would be strictly worse to have spent time writing the full backing type.1 parent 53775b0 commit d657b6c
File tree
6 files changed
+271
-73
lines changed- src
- test/behavior
6 files changed
+271
-73
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6607 | 6607 | | |
6608 | 6608 | | |
6609 | 6609 | | |
| 6610 | + | |
6610 | 6611 | | |
6611 | 6612 | | |
6612 | 6613 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
27260 | 27260 | | |
27261 | 27261 | | |
27262 | 27262 | | |
27263 | | - | |
| 27263 | + | |
27264 | 27264 | | |
27265 | 27265 | | |
27266 | 27266 | | |
| |||
29781 | 29781 | | |
29782 | 29782 | | |
29783 | 29783 | | |
29784 | | - | |
29785 | | - | |
29786 | | - | |
29787 | | - | |
29788 | | - | |
29789 | | - | |
29790 | | - | |
| 29784 | + | |
| 29785 | + | |
| 29786 | + | |
| 29787 | + | |
| 29788 | + | |
| 29789 | + | |
| 29790 | + | |
| 29791 | + | |
| 29792 | + | |
| 29793 | + | |
| 29794 | + | |
| 29795 | + | |
| 29796 | + | |
29791 | 29797 | | |
29792 | 29798 | | |
29793 | 29799 | | |
| |||
29819 | 29825 | | |
29820 | 29826 | | |
29821 | 29827 | | |
| 29828 | + | |
| 29829 | + | |
29822 | 29830 | | |
29823 | 29831 | | |
29824 | 29832 | | |
| |||
30182 | 30190 | | |
30183 | 30191 | | |
30184 | 30192 | | |
30185 | | - | |
30186 | | - | |
30187 | | - | |
30188 | 30193 | | |
30189 | | - | |
| 30194 | + | |
30190 | 30195 | | |
30191 | | - | |
30192 | | - | |
30193 | | - | |
30194 | | - | |
30195 | | - | |
30196 | | - | |
30197 | | - | |
30198 | | - | |
30199 | | - | |
| 30196 | + | |
| 30197 | + | |
| 30198 | + | |
| 30199 | + | |
| 30200 | + | |
| 30201 | + | |
| 30202 | + | |
| 30203 | + | |
| 30204 | + | |
| 30205 | + | |
| 30206 | + | |
| 30207 | + | |
| 30208 | + | |
| 30209 | + | |
| 30210 | + | |
| 30211 | + | |
| 30212 | + | |
| 30213 | + | |
| 30214 | + | |
| 30215 | + | |
| 30216 | + | |
| 30217 | + | |
| 30218 | + | |
| 30219 | + | |
| 30220 | + | |
| 30221 | + | |
| 30222 | + | |
| 30223 | + | |
| 30224 | + | |
| 30225 | + | |
| 30226 | + | |
| 30227 | + | |
| 30228 | + | |
| 30229 | + | |
30200 | 30230 | | |
30201 | 30231 | | |
30202 | 30232 | | |
| |||
30697 | 30727 | | |
30698 | 30728 | | |
30699 | 30729 | | |
| 30730 | + | |
30700 | 30731 | | |
30701 | 30732 | | |
30702 | 30733 | | |
| |||
30713 | 30744 | | |
30714 | 30745 | | |
30715 | 30746 | | |
| 30747 | + | |
| 30748 | + | |
| 30749 | + | |
| 30750 | + | |
| 30751 | + | |
| 30752 | + | |
| 30753 | + | |
| 30754 | + | |
| 30755 | + | |
| 30756 | + | |
| 30757 | + | |
| 30758 | + | |
| 30759 | + | |
| 30760 | + | |
| 30761 | + | |
| 30762 | + | |
| 30763 | + | |
| 30764 | + | |
| 30765 | + | |
| 30766 | + | |
| 30767 | + | |
| 30768 | + | |
| 30769 | + | |
| 30770 | + | |
| 30771 | + | |
| 30772 | + | |
| 30773 | + | |
| 30774 | + | |
| 30775 | + | |
| 30776 | + | |
| 30777 | + | |
| 30778 | + | |
| 30779 | + | |
30716 | 30780 | | |
30717 | 30781 | | |
30718 | 30782 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
84 | 84 | | |
85 | 85 | | |
86 | 86 | | |
87 | | - | |
| 87 | + | |
88 | 88 | | |
89 | 89 | | |
90 | | - | |
| 90 | + | |
91 | 91 | | |
92 | 92 | | |
93 | | - | |
| 93 | + | |
94 | 94 | | |
95 | 95 | | |
96 | | - | |
| 96 | + | |
97 | 97 | | |
98 | 98 | | |
99 | | - | |
| 99 | + | |
100 | 100 | | |
101 | 101 | | |
102 | | - | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
103 | 108 | | |
104 | 109 | | |
105 | 110 | | |
| |||
421 | 426 | | |
422 | 427 | | |
423 | 428 | | |
424 | | - | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
425 | 435 | | |
426 | 436 | | |
427 | 437 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1954 | 1954 | | |
1955 | 1955 | | |
1956 | 1956 | | |
| 1957 | + | |
| 1958 | + | |
| 1959 | + | |
| 1960 | + | |
| 1961 | + | |
| 1962 | + | |
| 1963 | + | |
| 1964 | + | |
| 1965 | + | |
| 1966 | + | |
1957 | 1967 | | |
1958 | 1968 | | |
1959 | 1969 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
327 | 327 | | |
328 | 328 | | |
329 | 329 | | |
330 | | - | |
331 | | - | |
332 | | - | |
333 | | - | |
334 | | - | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
335 | 343 | | |
336 | 344 | | |
337 | 345 | | |
| |||
399 | 407 | | |
400 | 408 | | |
401 | 409 | | |
402 | | - | |
403 | | - | |
404 | | - | |
405 | | - | |
| 410 | + | |
406 | 411 | | |
407 | 412 | | |
408 | 413 | | |
| |||
709 | 714 | | |
710 | 715 | | |
711 | 716 | | |
712 | | - | |
713 | 717 | | |
| 718 | + | |
714 | 719 | | |
715 | 720 | | |
716 | 721 | | |
717 | 722 | | |
718 | 723 | | |
719 | 724 | | |
720 | | - | |
721 | | - | |
722 | | - | |
| 725 | + | |
| 726 | + | |
| 727 | + | |
723 | 728 | | |
724 | 729 | | |
725 | 730 | | |
726 | | - | |
| 731 | + | |
| 732 | + | |
727 | 733 | | |
728 | 734 | | |
729 | 735 | | |
| |||
842 | 848 | | |
843 | 849 | | |
844 | 850 | | |
845 | | - | |
846 | | - | |
847 | | - | |
| 851 | + | |
| 852 | + | |
848 | 853 | | |
849 | 854 | | |
850 | 855 | | |
| |||
1146 | 1151 | | |
1147 | 1152 | | |
1148 | 1153 | | |
1149 | | - | |
1150 | | - | |
1151 | | - | |
1152 | | - | |
| 1154 | + | |
| 1155 | + | |
1153 | 1156 | | |
1154 | 1157 | | |
1155 | 1158 | | |
| |||
4017 | 4020 | | |
4018 | 4021 | | |
4019 | 4022 | | |
4020 | | - | |
| 4023 | + | |
4021 | 4024 | | |
4022 | 4025 | | |
4023 | 4026 | | |
| |||
0 commit comments