Sema: Add error for non-power of 2 field alignment when reifying Unions, Structs, Pointers

This commit is contained in:
Krzysztof Wolicki 2023-11-16 08:19:54 +00:00 committed by GitHub
parent 359842f8d5
commit acf9de376d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 4 deletions

View File

@ -20431,9 +20431,11 @@ fn zirReify(
return sema.fail(block, src, "alignment must fit in 'u32'", .{}); return sema.fail(block, src, "alignment must fit in 'u32'", .{});
} }
const abi_align = Alignment.fromByteUnits( const alignment_val_int = (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?;
(try alignment_val.getUnsignedIntAdvanced(mod, sema)).?, if (alignment_val_int > 0 and !math.isPowerOfTwo(alignment_val_int)) {
); return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{alignment_val_int});
}
const abi_align = Alignment.fromByteUnits(alignment_val_int);
const elem_ty = child_val.toType(); const elem_ty = child_val.toType();
if (abi_align != .none) { if (abi_align != .none) {
@ -20895,7 +20897,14 @@ fn zirReify(
} }
const field_ty = type_val.toType(); const field_ty = type_val.toType();
const field_align = Alignment.fromByteUnits((try alignment_val.getUnsignedIntAdvanced(mod, sema)).?); const alignment_val_int = (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?;
if (alignment_val_int > 0 and !math.isPowerOfTwo(alignment_val_int)) {
// TODO: better source location
return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{
alignment_val_int,
});
}
const field_align = Alignment.fromByteUnits(alignment_val_int);
any_aligned_fields = any_aligned_fields or field_align != .none; any_aligned_fields = any_aligned_fields or field_align != .none;
try union_fields.append(sema.arena, .{ try union_fields.append(sema.arena, .{
@ -21214,6 +21223,7 @@ fn reifyStruct(
if (abi_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{}); if (abi_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{});
if (is_comptime_val.toBool()) return sema.fail(block, src, "packed struct fields cannot be marked comptime", .{}); if (is_comptime_val.toBool()) return sema.fail(block, src, "packed struct fields cannot be marked comptime", .{});
} else { } else {
if (abi_align > 0 and !math.isPowerOfTwo(abi_align)) return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{abi_align});
struct_type.field_aligns.get(ip)[i] = Alignment.fromByteUnits(abi_align); struct_type.field_aligns.get(ip)[i] = Alignment.fromByteUnits(abi_align);
} }
if (layout == .Extern and is_comptime_val.toBool()) { if (layout == .Extern and is_comptime_val.toBool()) {

View File

@ -0,0 +1,50 @@
comptime {
_ = @Type(.{
.Union = .{
.layout = .Auto,
.tag_type = null,
.fields = &.{
.{ .name = "foo", .type = usize, .alignment = 3 },
},
.decls = &.{},
},
});
}
comptime {
_ = @Type(.{
.Struct = .{
.layout = .Auto,
.fields = &.{.{
.name = "0",
.type = u32,
.default_value = null,
.is_comptime = true,
.alignment = 5,
}},
.decls = &.{},
.is_tuple = false,
},
});
}
comptime {
_ = @Type(.{
.Pointer = .{
.size = .Many,
.is_const = true,
.is_volatile = false,
.alignment = 7,
.address_space = .generic,
.child = u8,
.is_allowzero = false,
.sentinel = null,
},
});
}
// error
// backend=stage2
// target=native
//
// :2:9: error: alignment value '3' is not a power of two or zero
// :14:9: error: alignment value '5' is not a power of two or zero
// :30:9: error: alignment value '7' is not a power of two or zero