authorgravatar for 51252236+xdBronch@users.noreply.github.comxdBronch <51252236+xdBronch@users.noreply.github.com> 2025-10-13 17:25:00-04:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-10-16 19:36:11+01:00
logf785e4745d85f7056ab670989c5739b62b0df265
treee1f50a9768f3856e0175ca2e234da9aff0f1ed91
parent173f497e29daf377a6b843e6ed8cdddc12ceb712

detect invalid `@bitCast` with arrays


3 files changed, 56 insertions(+), 5 deletions(-)

src/Sema.zig+24-2
......@@ -9952,8 +9952,19 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
99529952 dest_ty.fmt(pt), container,
99539953 });
99549954 },
9955 .array => {
9956 const elem_ty = dest_ty.childType(zcu);
9957 if (!elem_ty.hasWellDefinedLayout(zcu)) {
9958 const msg = msg: {
9959 const msg = try sema.errMsg(src, "cannot @bitCast to '{f}'", .{dest_ty.fmt(pt)});
9960 errdefer msg.destroy(sema.gpa);
9961 try sema.errNote(src, msg, "array element type '{f}' does not have a guaranteed in-memory layout", .{elem_ty.fmt(pt)});
9962 break :msg msg;
9963 };
9964 return sema.failWithOwnedErrorMsg(block, msg);
9965 }
9966 },
99559967
9956 .array,
99579968 .bool,
99589969 .float,
99599970 .int,
......@@ -10015,8 +10026,19 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1001510026 operand_ty.fmt(pt), container,
1001610027 });
1001710028 },
10029 .array => {
10030 const elem_ty = operand_ty.childType(zcu);
10031 if (!elem_ty.hasWellDefinedLayout(zcu)) {
10032 const msg = msg: {
10033 const msg = try sema.errMsg(src, "cannot @bitCast from '{f}'", .{operand_ty.fmt(pt)});
10034 errdefer msg.destroy(sema.gpa);
10035 try sema.errNote(src, msg, "array element type '{f}' does not have a guaranteed in-memory layout", .{elem_ty.fmt(pt)});
10036 break :msg msg;
10037 };
10038 return sema.failWithOwnedErrorMsg(block, msg);
10039 }
10040 },
1001810041
10019 .array,
1002010042 .bool,
1002110043 .float,
1002210044 .int,
src/Type.zig+6-3
......@@ -1924,9 +1924,12 @@ pub fn isPtrLikeOptional(ty: Type, zcu: *const Zcu) bool {
19241924 };
19251925}
19261926
1927/// For *[N]T, returns [N]T.
1928/// For *T, returns T.
1929/// For [*]T, returns T.
1927/// For *[N]T, returns [N]T.
1928/// For *T, returns T.
1929/// For [*]T, returns T.
1930/// For @Vector(N, T), returns T.
1931/// For [N]T, returns T.
1932/// For ?T, returns T.
19301933pub fn childType(ty: Type, zcu: *const Zcu) Type {
19311934 return childTypeIp(ty, &zcu.intern_pool);
19321935}
test/cases/compile_errors/bitCast_with_invalid_array_element_type.zig created+26
......@@ -0,0 +1,26 @@
1export fn foo() void {
2 const S = struct {
3 f: u8,
4 };
5 _ = @as([@sizeOf(S)]u8, @bitCast([1]S{undefined}));
6}
7
8export fn bar() void {
9 const S = struct {
10 f: u8,
11 };
12 _ = @as([1]S, @bitCast(@as([@sizeOf(S)]u8, undefined)));
13}
14
15export fn baz() void {
16 _ = @as([1]u32, @bitCast([1]comptime_int{0}));
17}
18
19// error
20//
21// :5:29: error: cannot @bitCast from '[1]tmp.foo.S'
22// :5:29: note: array element type 'tmp.foo.S' does not have a guaranteed in-memory layout
23// :12:19: error: cannot @bitCast to '[1]tmp.bar.S'
24// :12:19: note: array element type 'tmp.bar.S' does not have a guaranteed in-memory layout
25// :16:21: error: cannot @bitCast from '[1]comptime_int'
26// :16:21: note: array element type 'comptime_int' does not have a guaranteed in-memory layout