diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-02-20 22:40:41 -0500 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2019-02-20 22:40:41 -0500 |
| commit | 3ee9d06cbdb6bcaf561e7215c4c103c7ad65a72d (patch) | |
| tree | c9f612c22c8e2d2e1191a5aab8fc2bfaebf4cfcd /test | |
| parent | 079728752eca4cffbb4f7e8dc06d5e23b81d7627 (diff) | |
| download | zig-3ee9d06cbdb6bcaf561e7215c4c103c7ad65a72d.tar.gz zig-3ee9d06cbdb6bcaf561e7215c4c103c7ad65a72d.zip | |
packed structs support comptime bitcasting
* `type_size_store` is no longer a thing. loading and storing a pointer
to a value may dereference up to `@sizeOf(T)` bytes, even for
integers such as `u24`.
* fix `types_have_same_zig_comptime_repr` to not think that the
same `ZigTypeId` means the `ConstExprValue` neccesarily has the
same representation.
* implement `buf_write_value_bytes` and `buf_read_value_bytes` for
`ContainerLayoutPacked`
closes #1120
Diffstat (limited to 'test')
| -rw-r--r-- | test/compile_errors.zig | 4 | ||||
| -rw-r--r-- | test/stage1/behavior.zig | 1 | ||||
| -rw-r--r-- | test/stage1/behavior/bitcast.zig | 32 | ||||
| -rw-r--r-- | test/stage1/behavior/bugs/1120.zig | 23 |
4 files changed, 58 insertions, 2 deletions
diff --git a/test/compile_errors.zig b/test/compile_errors.zig index a9c748bcda..07e677b8ed 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -318,12 +318,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "reading past end of pointer casted array", \\comptime { \\ const array = "aoeu"; - \\ const slice = array[2..]; + \\ const slice = array[1..]; \\ const int_ptr = @ptrCast(*const u24, slice.ptr); \\ const deref = int_ptr.*; \\} , - ".tmp_source.zig:5:26: error: attempt to read 3 bytes from [4]u8 at index 2 which is 2 bytes", + ".tmp_source.zig:5:26: error: attempt to read 4 bytes from [4]u8 at index 1 which is 3 bytes", ); cases.add( diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig index df311637fa..708bb91ac0 100644 --- a/test/stage1/behavior.zig +++ b/test/stage1/behavior.zig @@ -11,6 +11,7 @@ comptime { _ = @import("behavior/bswap.zig"); _ = @import("behavior/bugs/1076.zig"); _ = @import("behavior/bugs/1111.zig"); + _ = @import("behavior/bugs/1120.zig"); _ = @import("behavior/bugs/1277.zig"); _ = @import("behavior/bugs/1322.zig"); _ = @import("behavior/bugs/1381.zig"); diff --git a/test/stage1/behavior/bitcast.zig b/test/stage1/behavior/bitcast.zig index 9607d2e3ef..e498905f4e 100644 --- a/test/stage1/behavior/bitcast.zig +++ b/test/stage1/behavior/bitcast.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const builtin = @import("builtin"); const expect = std.testing.expect; const maxInt = std.math.maxInt; @@ -34,3 +35,34 @@ test "@bitCast extern enum to its integer type" { SOCK.testBitCastExternEnum(); comptime SOCK.testBitCastExternEnum(); } + +test "@bitCast packed structs at runtime and comptime" { + const Full = packed struct { + number: u16, + }; + const Divided = packed struct { + half1: u8, + quarter3: u4, + quarter4: u4, + }; + const S = struct { + fn doTheTest() void { + var full = Full{ .number = 0x1234 }; + var two_halves = @bitCast(Divided, full); + switch (builtin.endian) { + builtin.Endian.Big => { + expect(two_halves.half1 == 0x12); + expect(two_halves.quarter3 == 0x3); + expect(two_halves.quarter4 == 0x4); + }, + builtin.Endian.Little => { + expect(two_halves.half1 == 0x34); + expect(two_halves.quarter3 == 0x2); + expect(two_halves.quarter4 == 0x1); + }, + } + } + }; + S.doTheTest(); + comptime S.doTheTest(); +} diff --git a/test/stage1/behavior/bugs/1120.zig b/test/stage1/behavior/bugs/1120.zig new file mode 100644 index 0000000000..dda46e8e1c --- /dev/null +++ b/test/stage1/behavior/bugs/1120.zig @@ -0,0 +1,23 @@ +const std = @import("std"); +const expect = std.testing.expect; + +const A = packed struct { + a: u2, + b: u6, +}; +const B = packed struct { + q: u8, + a: u2, + b: u6, +}; +test "bug 1120" { + var a = A{ .a = 2, .b = 2 }; + var b = B{ .q = 22, .a = 3, .b = 2 }; + var t: usize = 0; + const ptr = switch (t) { + 0 => &a.a, + 1 => &b.a, + else => unreachable, + }; + expect(ptr.* == 2); +} |
