detect invalid @bitCast with arrays

This commit is contained in:
xdBronch 2025-10-13 17:25:00 -04:00 committed by Matthew Lugg
parent 173f497e29
commit f785e4745d
3 changed files with 56 additions and 5 deletions

View File

@ -9952,8 +9952,19 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
dest_ty.fmt(pt), container,
});
},
.array => {
const elem_ty = dest_ty.childType(zcu);
if (!elem_ty.hasWellDefinedLayout(zcu)) {
const msg = msg: {
const msg = try sema.errMsg(src, "cannot @bitCast to '{f}'", .{dest_ty.fmt(pt)});
errdefer msg.destroy(sema.gpa);
try sema.errNote(src, msg, "array element type '{f}' does not have a guaranteed in-memory layout", .{elem_ty.fmt(pt)});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
}
},
.array,
.bool,
.float,
.int,
@ -10015,8 +10026,19 @@ fn zirBitcast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
operand_ty.fmt(pt), container,
});
},
.array => {
const elem_ty = operand_ty.childType(zcu);
if (!elem_ty.hasWellDefinedLayout(zcu)) {
const msg = msg: {
const msg = try sema.errMsg(src, "cannot @bitCast from '{f}'", .{operand_ty.fmt(pt)});
errdefer msg.destroy(sema.gpa);
try sema.errNote(src, msg, "array element type '{f}' does not have a guaranteed in-memory layout", .{elem_ty.fmt(pt)});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(block, msg);
}
},
.array,
.bool,
.float,
.int,

View File

@ -1924,9 +1924,12 @@ pub fn isPtrLikeOptional(ty: Type, zcu: *const Zcu) bool {
};
}
/// For *[N]T, returns [N]T.
/// For *T, returns T.
/// For [*]T, returns T.
/// For *[N]T, returns [N]T.
/// For *T, returns T.
/// For [*]T, returns T.
/// For @Vector(N, T), returns T.
/// For [N]T, returns T.
/// For ?T, returns T.
pub fn childType(ty: Type, zcu: *const Zcu) Type {
return childTypeIp(ty, &zcu.intern_pool);
}

View File

@ -0,0 +1,26 @@
export fn foo() void {
const S = struct {
f: u8,
};
_ = @as([@sizeOf(S)]u8, @bitCast([1]S{undefined}));
}
export fn bar() void {
const S = struct {
f: u8,
};
_ = @as([1]S, @bitCast(@as([@sizeOf(S)]u8, undefined)));
}
export fn baz() void {
_ = @as([1]u32, @bitCast([1]comptime_int{0}));
}
// error
//
// :5:29: error: cannot @bitCast from '[1]tmp.foo.S'
// :5:29: note: array element type 'tmp.foo.S' does not have a guaranteed in-memory layout
// :12:19: error: cannot @bitCast to '[1]tmp.bar.S'
// :12:19: note: array element type 'tmp.bar.S' does not have a guaranteed in-memory layout
// :16:21: error: cannot @bitCast from '[1]comptime_int'
// :16:21: note: array element type 'comptime_int' does not have a guaranteed in-memory layout