diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-12-28 01:52:19 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-12-28 01:53:58 -0700 |
| commit | 4b9b9e725777a8f9e4ea9391beaeea34c834615f (patch) | |
| tree | f1cbd788134cdbcde7f90dc2b9ada91dcd9159ba /test/behavior/switch.zig | |
| parent | 232f8a291d2debd8a0fe9df2ce36d9035a15aefb (diff) | |
| download | zig-4b9b9e725777a8f9e4ea9391beaeea34c834615f.tar.gz zig-4b9b9e725777a8f9e4ea9391beaeea34c834615f.zip | |
stage2: LLVM backend: fix lowering of union constants
Comment from this commit reproduced here:
LLVM does not allow us to change the type of globals. So we must
create a new global with the correct type, copy all its attributes,
and then update all references to point to the new global,
delete the original, and rename the new one to the old one's name.
This is necessary because LLVM does not support const bitcasting
a struct with padding bytes, which is needed to lower a const union value
to LLVM, when a field other than the most-aligned is active. Instead,
we must lower to an unnamed struct, and pointer cast at usage sites
of the global. Such an unnamed struct is the cause of the global type
mismatch, because we don't have the LLVM type until the *value* is created,
whereas the global needs to be created based on the type alone, because
lowering the value may reference the global as a pointer.
Diffstat (limited to 'test/behavior/switch.zig')
| -rw-r--r-- | test/behavior/switch.zig | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/test/behavior/switch.zig b/test/behavior/switch.zig index f5fc282b05..16bb890c9e 100644 --- a/test/behavior/switch.zig +++ b/test/behavior/switch.zig @@ -294,3 +294,22 @@ test "switch on union with some prongs capturing" { }; try expect(y == 11); } + +const Number = union(enum) { + One: u64, + Two: u8, + Three: f32, +}; + +const number = Number{ .Three = 1.23 }; + +fn returnsFalse() bool { + switch (number) { + Number.One => |x| return x > 1234, + Number.Two => |x| return x == 'a', + Number.Three => |x| return x > 12.34, + } +} +test "switch on const enum with var" { + try expect(!returnsFalse()); +} |
