Skip to content

Commit e88df05

Browse files
xdBronchxtexx
authored andcommitted
detect invalid @bitCast with arrays
(cherry picked from commit f785e47)
1 parent ab12211 commit e88df05

File tree

3 files changed

+56
-5
lines changed

3 files changed

+56
-5
lines changed

src/Sema.zig

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9947,8 +9947,19 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
99479947
dest_ty.fmt(pt), container,
99489948
});
99499949
},
9950+
.array => {
9951+
const elem_ty = dest_ty.childType(zcu);
9952+
if (!elem_ty.hasWellDefinedLayout(zcu)) {
9953+
const msg = msg: {
9954+
const msg = try sema.errMsg(src, "cannot @bitCast to '{f}'", .{dest_ty.fmt(pt)});
9955+
errdefer msg.destroy(sema.gpa);
9956+
try sema.errNote(src, msg, "array element type '{f}' does not have a guaranteed in-memory layout", .{elem_ty.fmt(pt)});
9957+
break :msg msg;
9958+
};
9959+
return sema.failWithOwnedErrorMsg(block, msg);
9960+
}
9961+
},
99509962

9951-
.array,
99529963
.bool,
99539964
.float,
99549965
.int,
@@ -10010,8 +10021,19 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
1001010021
operand_ty.fmt(pt), container,
1001110022
});
1001210023
},
10024+
.array => {
10025+
const elem_ty = operand_ty.childType(zcu);
10026+
if (!elem_ty.hasWellDefinedLayout(zcu)) {
10027+
const msg = msg: {
10028+
const msg = try sema.errMsg(src, "cannot @bitCast from '{f}'", .{operand_ty.fmt(pt)});
10029+
errdefer msg.destroy(sema.gpa);
10030+
try sema.errNote(src, msg, "array element type '{f}' does not have a guaranteed in-memory layout", .{elem_ty.fmt(pt)});
10031+
break :msg msg;
10032+
};
10033+
return sema.failWithOwnedErrorMsg(block, msg);
10034+
}
10035+
},
1001310036

10014-
.array,
1001510037
.bool,
1001610038
.float,
1001710039
.int,

src/Type.zig

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
19301933
pub fn childType(ty: Type, zcu: *const Zcu) Type {
19311934
return childTypeIp(ty, &zcu.intern_pool);
19321935
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
export fn foo() void {
2+
const S = struct {
3+
f: u8,
4+
};
5+
_ = @as([@sizeOf(S)]u8, @bitCast([1]S{undefined}));
6+
}
7+
8+
export fn bar() void {
9+
const S = struct {
10+
f: u8,
11+
};
12+
_ = @as([1]S, @bitCast(@as([@sizeOf(S)]u8, undefined)));
13+
}
14+
15+
export 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

0 commit comments

Comments
 (0)