diff --git a/src/Sema.zig b/src/Sema.zig index fd90c80910..2615a5b27d 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -20431,9 +20431,11 @@ fn zirReify( return sema.fail(block, src, "alignment must fit in 'u32'", .{}); } - const abi_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)) { + 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(); if (abi_align != .none) { @@ -20895,7 +20897,14 @@ fn zirReify( } 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; 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 (is_comptime_val.toBool()) return sema.fail(block, src, "packed struct fields cannot be marked comptime", .{}); } 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); } if (layout == .Extern and is_comptime_val.toBool()) { diff --git a/test/cases/compile_errors/reify_type_with_invalid_field_alignment.zig b/test/cases/compile_errors/reify_type_with_invalid_field_alignment.zig new file mode 100644 index 0000000000..dc57ded029 --- /dev/null +++ b/test/cases/compile_errors/reify_type_with_invalid_field_alignment.zig @@ -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