Skip to content

Commit f785e47

Browse files
xdBronchmlugg
authored andcommitted
detect invalid @bitCast with arrays
1 parent 173f497 commit f785e47

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
@@ -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

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)