compiler: Initialize constant slice backing names
82bcbace4262fff3016fe2e8f9959471ae605761c84411cb8c3ab6991e2dd7ed
1 parent
d335f485
lib/std/lang/lower.rad
+7 -13
| 1502 | 1502 | let layout = resolver::getTypeLayout(targetTy); |
|
| 1503 | 1503 | try lowerConstDataInto(self, addr.target, targetTy, layout.size, dataPrefix, &mut nested); |
|
| 1504 | 1504 | ||
| 1505 | 1505 | let backing = dataBuilderFinish(nested); |
|
| 1506 | 1506 | let readOnly = not mutable; |
|
| 1507 | - | let mut dataName: *[u8] = undefined; |
|
| 1507 | + | let mut found: ?*[u8] = nil; |
|
| 1508 | 1508 | if readOnly { |
|
| 1509 | - | if let found = findConstData(self, backing.values, layout.alignment) { |
|
| 1510 | - | set dataName = found; |
|
| 1511 | - | } else { |
|
| 1512 | - | set dataName = try pushDeclData(self, layout.size, layout.alignment, readOnly, backing.values, dataPrefix); |
|
| 1513 | - | } |
|
| 1514 | - | } else { |
|
| 1515 | - | set dataName = try pushDeclData(self, layout.size, layout.alignment, readOnly, backing.values, dataPrefix); |
|
| 1509 | + | set found = findConstData(self, backing.values, layout.alignment); |
|
| 1516 | 1510 | } |
|
| 1511 | + | let dataName = found else try pushDeclData( |
|
| 1512 | + | self, layout.size, layout.alignment, readOnly, backing.values, dataPrefix |
|
| 1513 | + | ); |
|
| 1517 | 1514 | dataSliceHeader(b, dataName, arrInfo.length); |
|
| 1518 | 1515 | } |
|
| 1519 | 1516 | ||
| 1520 | 1517 | /// Lower a constant expression payload into a builder without slot padding. |
|
| 1521 | 1518 | /// Compute the type layout when nil or undefined data needs a byte count. |
| 2021 | 2018 | length: u32 |
|
| 2022 | 2019 | ) -> il::Val throws (LowerError) where 'arena: 'phase, 'phase: 'function { |
|
| 2023 | 2020 | let values = result.values; |
|
| 2024 | 2021 | let elemLayout = resolver::getTypeLayout(*elemTy); |
|
| 2025 | 2022 | let size = elemLayout.size * length; |
|
| 2026 | - | let mut dataName: *[u8] = undefined; |
|
| 2027 | 2023 | let mut found: ?*[u8] = nil; |
|
| 2028 | 2024 | if readOnly { |
|
| 2029 | 2025 | set found = findConstData(self.low, values, alignment); |
|
| 2030 | 2026 | } |
|
| 2031 | - | if let name = found { |
|
| 2032 | - | set dataName = name; |
|
| 2033 | - | } else { |
|
| 2034 | - | set dataName = try nextDataName(self); |
|
| 2027 | + | let dataName = found else try nextDataName(self); |
|
| 2028 | + | if found == nil { |
|
| 2035 | 2029 | self.low.data.append(il::Data { |
|
| 2036 | 2030 | name: dataName, |
|
| 2037 | 2031 | size, |
|
| 2038 | 2032 | alignment, |
|
| 2039 | 2033 | readOnly, |
test/tests/literal.slice.backing.rad
added
+27 -0
| 1 | + | //! returns: 0 |
|
| 2 | + | ||
| 3 | + | /// Nested constant slices with repeated backing contents. |
|
| 4 | + | constant GROUPS: [*[u32]; 3] = [&[11, 22, 33], &[11, 22, 33], &[44, 55]]; |
|
| 5 | + | ||
| 6 | + | /// Check immutable reuse and independent writable literal storage. |
|
| 7 | + | @default unsafe fn main() -> u32 { |
|
| 8 | + | let first: *[u32] = &[11, 22, 33]; |
|
| 9 | + | let second: *[u32] = &[11, 22, 33]; |
|
| 10 | + | assert first.ptr == second.ptr; |
|
| 11 | + | assert GROUPS[0].ptr == GROUPS[1].ptr; |
|
| 12 | + | assert GROUPS[0][2] == 33; |
|
| 13 | + | assert GROUPS[2][1] == 55; |
|
| 14 | + | let left: *mut [u32] = &mut [11, 22, 33]; |
|
| 15 | + | let right: *mut [u32] = &mut [11, 22, 33]; |
|
| 16 | + | set left[1] = 99; |
|
| 17 | + | assert left[1] == 99; |
|
| 18 | + | assert right[1] == 22; |
|
| 19 | + | assert first[1] == 22; |
|
| 20 | + | assert GROUPS[0][1] == 22; |
|
| 21 | + | let zeros: *mut [u32] = &mut [0 as u32; 4]; |
|
| 22 | + | let moreZeros: *mut [u32] = &mut [0 as u32; 4]; |
|
| 23 | + | set zeros[3] = 7; |
|
| 24 | + | assert zeros[0] == 0; |
|
| 25 | + | assert moreZeros[3] == 0; |
|
| 26 | + | return 0; |
|
| 27 | + | } |