compiler: Initialize remaining lowering temporaries
09f9be49f93cc2df9016f55a26fbbdc3f575a38effbdf40cfdb56711b8b9679d
1 parent
49408f75
lib/std/lang/lower.rad
+4 -8
| 1332 | 1332 | } |
|
| 1333 | 1333 | ||
| 1334 | 1334 | /// Create a label with a numeric suffix, eg. `@base0`. |
|
| 1335 | 1335 | /// This ensures unique labels like `@then0`, `@then1`, etc. |
|
| 1336 | 1336 | unsafe fn labelWithSuffix 'arena 'phase 'function (self: &mut FnLowerer 'arena 'phase 'function, base: *[u8], suffix: u32) -> *[u8] throws (LowerError) where 'arena: 'phase, 'phase: 'function { |
|
| 1337 | - | let mut digits: [u8; fmt::U32_STR_LEN] = undefined; |
|
| 1337 | + | let mut digits: [u8; fmt::U32_STR_LEN] = [0; fmt::U32_STR_LEN]; |
|
| 1338 | 1338 | let start = fmt::formatU32(suffix, &mut digits[..]); |
|
| 1339 | 1339 | let totalLen = base.len + digits.len - start; |
|
| 1340 | 1340 | let buf = try! alloc::allocSlice(self.arena, 1, 1, totalLen) as *mut [u8]; |
|
| 1341 | 1341 | ||
| 1342 | 1342 | try! mem::copy(&mut buf[..base.len], base); |
| 1875 | 1875 | self: &mut Lowerer 'arena 'phase, |
|
| 1876 | 1876 | prefix: *[u8], |
|
| 1877 | 1877 | count: u32, |
|
| 1878 | 1878 | namespace: *[u8] |
|
| 1879 | 1879 | ) -> *[u8] throws (LowerError) where 'arena: 'phase { |
|
| 1880 | - | let mut digits: [u8; fmt::U32_STR_LEN] = undefined; |
|
| 1880 | + | let mut digits: [u8; fmt::U32_STR_LEN] = [0; fmt::U32_STR_LEN]; |
|
| 1881 | 1881 | let start = fmt::formatU32(count, &mut digits[..]); |
|
| 1882 | 1882 | let suffix = try! alloc::allocSlice(self.arena, 1, 1, digits.len - start) as *mut [u8]; |
|
| 1883 | 1883 | try! mem::copy(suffix, &digits[start..]); |
|
| 1884 | 1884 | let segments = [prefix, namespace, suffix]; |
|
| 1885 | 1885 |
| 4588 | 4588 | throws (LowerError) where 'arena: 'phase, 'phase: 'function |
|
| 4589 | 4589 | { |
|
| 4590 | 4590 | let reg = emitValToReg(self, val); |
|
| 4591 | 4591 | ||
| 4592 | 4592 | // For all-void unions, the value *is* the tag, not a pointer. |
|
| 4593 | - | let mut tag: il::Val = undefined; |
|
| 4594 | - | if resolver::isVoidUnion(valType) { |
|
| 4595 | - | set tag = il::Val::Reg(reg); |
|
| 4596 | - | } else { |
|
| 4597 | - | set tag = loadTag(self, reg, TVAL_TAG_OFFSET, il::Type::W8); |
|
| 4598 | - | } |
|
| 4593 | + | let tag = il::Val::Reg(reg) if resolver::isVoidUnion(valType) |
|
| 4594 | + | else loadTag(self, reg, TVAL_TAG_OFFSET, il::Type::W8); |
|
| 4599 | 4595 | let binOp = il::BinOp::Eq if op == ast::BinaryOp::Eq else il::BinOp::Ne; |
|
| 4600 | 4596 | return emitTypedBinOp(self, binOp, il::Type::W8, tag, il::Val::Imm(tagIdx)); |
|
| 4601 | 4597 | } |
|
| 4602 | 4598 | ||
| 4603 | 4599 | /// Logical "and" between two values. Returns the result in a register. |
test/tests/union.tag.values.rad
added
+44 -0
| 1 | + | //! returns: 0 |
|
| 2 | + | ||
| 3 | + | /// All-void unions carry their tag directly. |
|
| 4 | + | union Simple: Copy { |
|
| 5 | + | /// First tag. |
|
| 6 | + | First, |
|
| 7 | + | /// Second tag. |
|
| 8 | + | Second, |
|
| 9 | + | /// Third tag. |
|
| 10 | + | Third, |
|
| 11 | + | } |
|
| 12 | + | ||
| 13 | + | /// Payload unions store their tag in an aggregate. |
|
| 14 | + | union Mixed: Copy { |
|
| 15 | + | /// First void tag. |
|
| 16 | + | Empty, |
|
| 17 | + | /// Second void tag. |
|
| 18 | + | Other, |
|
| 19 | + | /// Full-width payload. |
|
| 20 | + | Value(u64), |
|
| 21 | + | } |
|
| 22 | + | ||
| 23 | + | /// Check both comparison directions and both tag representations. |
|
| 24 | + | @default fn main() -> u32 { |
|
| 25 | + | let simple = [Simple::First, Simple::Second, Simple::Third]; |
|
| 26 | + | for value, index in simple { |
|
| 27 | + | assert (value == Simple::First) == (index == 0); |
|
| 28 | + | assert (Simple::First == value) == (index == 0); |
|
| 29 | + | assert (value <> Simple::Second) == (index <> 1); |
|
| 30 | + | assert (Simple::Second <> value) == (index <> 1); |
|
| 31 | + | assert (value == Simple::Third) == (index == 2); |
|
| 32 | + | } |
|
| 33 | + | let mixed = [Mixed::Empty, Mixed::Other, Mixed::Value(0), Mixed::Value(0xffffffffffffffff)]; |
|
| 34 | + | for value, index in mixed { |
|
| 35 | + | assert (value == Mixed::Empty) == (index == 0); |
|
| 36 | + | assert (Mixed::Empty == value) == (index == 0); |
|
| 37 | + | assert (value <> Mixed::Empty) == (index <> 0); |
|
| 38 | + | assert (Mixed::Empty <> value) == (index <> 0); |
|
| 39 | + | assert (value == Mixed::Other) == (index == 1); |
|
| 40 | + | assert (Mixed::Other == value) == (index == 1); |
|
| 41 | + | assert (value <> Mixed::Other) == (index <> 1); |
|
| 42 | + | } |
|
| 43 | + | return 0; |
|
| 44 | + | } |