authorgravatar for der.teufel.mail@gmail.comKrzysztof Wolicki <der.teufel.mail@gmail.com> 2023-11-16 08:19:54+00:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-11-16 10:19:54+02:00
logacf9de376d176d35dcfd245d14939766aeba4638
treed2aed2f72db0586b2ff1500c58f432b79af7e7a1
parent359842f8d5a0ee2641c07c1e659d06553d6269fc
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

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


2 files changed, 64 insertions(+), 4 deletions(-)

src/Sema.zig+14-4
...@@ -20431,9 +20431,11 @@ fn zirReify(...@@ -20431,9 +20431,11 @@ fn zirReify(
20431 return sema.fail(block, src, "alignment must fit in 'u32'", .{});20431 return sema.fail(block, src, "alignment must fit in 'u32'", .{});
20432 }20432 }
2043320433
20434 const abi_align = Alignment.fromByteUnits(20434 const alignment_val_int = (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?;
20435 (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?,20435 if (alignment_val_int > 0 and !math.isPowerOfTwo(alignment_val_int)) {
20436 );20436 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{alignment_val_int});
20437 }
20438 const abi_align = Alignment.fromByteUnits(alignment_val_int);
2043720439
20438 const elem_ty = child_val.toType();20440 const elem_ty = child_val.toType();
20439 if (abi_align != .none) {20441 if (abi_align != .none) {
...@@ -20895,7 +20897,14 @@ fn zirReify(...@@ -20895,7 +20897,14 @@ fn zirReify(
20895 }20897 }
2089620898
20897 const field_ty = type_val.toType();20899 const field_ty = type_val.toType();
20898 const field_align = Alignment.fromByteUnits((try alignment_val.getUnsignedIntAdvanced(mod, sema)).?);20900 const alignment_val_int = (try alignment_val.getUnsignedIntAdvanced(mod, sema)).?;
20901 if (alignment_val_int > 0 and !math.isPowerOfTwo(alignment_val_int)) {
20902 // TODO: better source location
20903 return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{
20904 alignment_val_int,
20905 });
20906 }
20907 const field_align = Alignment.fromByteUnits(alignment_val_int);
20899 any_aligned_fields = any_aligned_fields or field_align != .none;20908 any_aligned_fields = any_aligned_fields or field_align != .none;
2090020909
20901 try union_fields.append(sema.arena, .{20910 try union_fields.append(sema.arena, .{
...@@ -21214,6 +21223,7 @@ fn reifyStruct(...@@ -21214,6 +21223,7 @@ fn reifyStruct(
21214 if (abi_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{});21223 if (abi_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{});
21215 if (is_comptime_val.toBool()) return sema.fail(block, src, "packed struct fields cannot be marked comptime", .{});21224 if (is_comptime_val.toBool()) return sema.fail(block, src, "packed struct fields cannot be marked comptime", .{});
21216 } else {21225 } else {
21226 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});
21217 struct_type.field_aligns.get(ip)[i] = Alignment.fromByteUnits(abi_align);21227 struct_type.field_aligns.get(ip)[i] = Alignment.fromByteUnits(abi_align);
21218 }21228 }
21219 if (layout == .Extern and is_comptime_val.toBool()) {21229 if (layout == .Extern and is_comptime_val.toBool()) {
test/cases/compile_errors/reify_type_with_invalid_field_alignment.zig created+50
...@@ -0,0 +1,50 @@
1comptime {
2 _ = @Type(.{
3 .Union = .{
4 .layout = .Auto,
5 .tag_type = null,
6 .fields = &.{
7 .{ .name = "foo", .type = usize, .alignment = 3 },
8 },
9 .decls = &.{},
10 },
11 });
12}
13comptime {
14 _ = @Type(.{
15 .Struct = .{
16 .layout = .Auto,
17 .fields = &.{.{
18 .name = "0",
19 .type = u32,
20 .default_value = null,
21 .is_comptime = true,
22 .alignment = 5,
23 }},
24 .decls = &.{},
25 .is_tuple = false,
26 },
27 });
28}
29comptime {
30 _ = @Type(.{
31 .Pointer = .{
32 .size = .Many,
33 .is_const = true,
34 .is_volatile = false,
35 .alignment = 7,
36 .address_space = .generic,
37 .child = u8,
38 .is_allowzero = false,
39 .sentinel = null,
40 },
41 });
42}
43
44// error
45// backend=stage2
46// target=native
47//
48// :2:9: error: alignment value '3' is not a power of two or zero
49// :14:9: error: alignment value '5' is not a power of two or zero
50// :30:9: error: alignment value '7' is not a power of two or zero