| ... | @@ -2649,7 +2649,13 @@ pub fn analyzeAsAlign( | ... | @@ -2649,7 +2649,13 @@ pub fn analyzeAsAlign( |
| 2649 | src: LazySrcLoc, | 2649 | src: LazySrcLoc, |
| 2650 | air_ref: Air.Inst.Ref, | 2650 | air_ref: Air.Inst.Ref, |
| 2651 | ) !Alignment { | 2651 | ) !Alignment { |
| 2652 | const alignment_big = try sema.analyzeAsInt(block, src, air_ref, align_ty, .{ .simple = .@"align" }); | 2652 | const alignment_big = try sema.analyzeAsInt( |
| | 2653 | block, |
| | 2654 | src, |
| | 2655 | air_ref, |
| | 2656 | align_ty, |
| | 2657 | .{ .simple = .@"align" }, |
| | 2658 | ); |
| 2653 | return sema.validateAlign(block, src, alignment_big); | 2659 | return sema.validateAlign(block, src, alignment_big); |
| 2654 | } | 2660 | } |
| 2655 | | 2661 | |
| ... | @@ -18807,7 +18813,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -18807,7 +18813,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 18807 | const abi_align: Alignment = if (inst_data.flags.has_align) blk: { | 18813 | const abi_align: Alignment = if (inst_data.flags.has_align) blk: { |
| 18808 | const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]); | 18814 | const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]); |
| 18809 | extra_i += 1; | 18815 | extra_i += 1; |
| 18810 | const coerced = try sema.coerce(block, .u32, try sema.resolveInst(ref), align_src); | 18816 | const coerced = try sema.coerce(block, align_ty, try sema.resolveInst(ref), align_src); |
| 18811 | const val = try sema.resolveConstDefinedValue(block, align_src, coerced, .{ .simple = .@"align" }); | 18817 | const val = try sema.resolveConstDefinedValue(block, align_src, coerced, .{ .simple = .@"align" }); |
| 18812 | // Check if this happens to be the lazy alignment of our element type, in | 18818 | // Check if this happens to be the lazy alignment of our element type, in |
| 18813 | // which case we can make this 0 without resolving it. | 18819 | // which case we can make this 0 without resolving it. |
| ... | @@ -20325,15 +20331,11 @@ fn zirReify( | ... | @@ -20325,15 +20331,11 @@ fn zirReify( |
| 20325 | try ip.getOrPutString(gpa, pt.tid, "sentinel_ptr", .no_embedded_nulls), | 20331 | try ip.getOrPutString(gpa, pt.tid, "sentinel_ptr", .no_embedded_nulls), |
| 20326 | ).?); | 20332 | ).?); |
| 20327 | | 20333 | |
| 20328 | if (!try sema.intFitsInType(alignment_val, .u32, null)) { | 20334 | if (!try sema.intFitsInType(alignment_val, align_ty, null)) { |
| 20329 | return sema.fail(block, src, "alignment must fit in 'u32'", .{}); | 20335 | return sema.fail(block, src, "alignment must fit in '{}'", .{align_ty.fmt(pt)}); |
| 20330 | } | 20336 | } |
| 20331 | | | |
| 20332 | const alignment_val_int = try alignment_val.toUnsignedIntSema(pt); | 20337 | const alignment_val_int = try alignment_val.toUnsignedIntSema(pt); |
| 20333 | if (alignment_val_int > 0 and !math.isPowerOfTwo(alignment_val_int)) { | 20338 | const abi_align = try sema.validateAlign(block, src, alignment_val_int); |
| 20334 | return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{alignment_val_int}); | | |
| 20335 | } | | |
| 20336 | const abi_align = Alignment.fromByteUnits(alignment_val_int); | | |
| 20337 | | 20339 | |
| 20338 | const elem_ty = child_val.toType(); | 20340 | const elem_ty = child_val.toType(); |
| 20339 | if (abi_align != .none) { | 20341 | if (abi_align != .none) { |
| ... | @@ -21017,11 +21019,7 @@ fn reifyUnion( | ... | @@ -21017,11 +21019,7 @@ fn reifyUnion( |
| 21017 | field_ty.* = field_type_val.toIntern(); | 21019 | field_ty.* = field_type_val.toIntern(); |
| 21018 | if (any_aligns) { | 21020 | if (any_aligns) { |
| 21019 | const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt); | 21021 | const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt); |
| 21020 | if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) { | 21022 | field_aligns[field_idx] = try sema.validateAlign(block, src, byte_align); |
| 21021 | // TODO: better source location | | |
| 21022 | return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align}); | | |
| 21023 | } | | |
| 21024 | field_aligns[field_idx] = Alignment.fromByteUnits(byte_align); | | |
| 21025 | } | 21023 | } |
| 21026 | } | 21024 | } |
| 21027 | | 21025 | |
| ... | @@ -21062,11 +21060,7 @@ fn reifyUnion( | ... | @@ -21062,11 +21060,7 @@ fn reifyUnion( |
| 21062 | field_ty.* = field_type_val.toIntern(); | 21060 | field_ty.* = field_type_val.toIntern(); |
| 21063 | if (any_aligns) { | 21061 | if (any_aligns) { |
| 21064 | const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt); | 21062 | const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt); |
| 21065 | if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) { | 21063 | field_aligns[field_idx] = try sema.validateAlign(block, src, byte_align); |
| 21066 | // TODO: better source location | | |
| 21067 | return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align}); | | |
| 21068 | } | | |
| 21069 | field_aligns[field_idx] = Alignment.fromByteUnits(byte_align); | | |
| 21070 | } | 21064 | } |
| 21071 | } | 21065 | } |
| 21072 | | 21066 | |
| ... | @@ -21266,7 +21260,6 @@ fn reifyStruct( | ... | @@ -21266,7 +21260,6 @@ fn reifyStruct( |
| 21266 | | 21260 | |
| 21267 | var any_comptime_fields = false; | 21261 | var any_comptime_fields = false; |
| 21268 | var any_default_inits = false; | 21262 | var any_default_inits = false; |
| 21269 | var any_aligned_fields = false; | | |
| 21270 | | 21263 | |
| 21271 | for (0..fields_len) |field_idx| { | 21264 | for (0..fields_len) |field_idx| { |
| 21272 | const field_info = try fields_val.elemValue(pt, field_idx); | 21265 | const field_info = try fields_val.elemValue(pt, field_idx); |
| ... | @@ -21301,11 +21294,6 @@ fn reifyStruct( | ... | @@ -21301,11 +21294,6 @@ fn reifyStruct( |
| 21301 | | 21294 | |
| 21302 | if (field_is_comptime) any_comptime_fields = true; | 21295 | if (field_is_comptime) any_comptime_fields = true; |
| 21303 | if (field_default_value != .none) any_default_inits = true; | 21296 | if (field_default_value != .none) any_default_inits = true; |
| 21304 | switch (try field_alignment_val.orderAgainstZeroSema(pt)) { | | |
| 21305 | .eq => {}, | | |
| 21306 | .gt => any_aligned_fields = true, | | |
| 21307 | .lt => unreachable, | | |
| 21308 | } | | |
| 21309 | } | 21297 | } |
| 21310 | | 21298 | |
| 21311 | const tracked_inst = try block.trackZir(inst); | 21299 | const tracked_inst = try block.trackZir(inst); |
| ... | @@ -21317,7 +21305,7 @@ fn reifyStruct( | ... | @@ -21317,7 +21305,7 @@ fn reifyStruct( |
| 21317 | .requires_comptime = .unknown, | 21305 | .requires_comptime = .unknown, |
| 21318 | .any_comptime_fields = any_comptime_fields, | 21306 | .any_comptime_fields = any_comptime_fields, |
| 21319 | .any_default_inits = any_default_inits, | 21307 | .any_default_inits = any_default_inits, |
| 21320 | .any_aligned_fields = any_aligned_fields, | 21308 | .any_aligned_fields = true, |
| 21321 | .inits_resolved = true, | 21309 | .inits_resolved = true, |
| 21322 | .key = .{ .reified = .{ | 21310 | .key = .{ .reified = .{ |
| 21323 | .zir_index = tracked_inst, | 21311 | .zir_index = tracked_inst, |
| ... | @@ -21361,21 +21349,14 @@ fn reifyStruct( | ... | @@ -21361,21 +21349,14 @@ fn reifyStruct( |
| 21361 | return sema.fail(block, src, "duplicate struct field name {f}", .{field_name.fmt(ip)}); | 21349 | return sema.fail(block, src, "duplicate struct field name {f}", .{field_name.fmt(ip)}); |
| 21362 | } | 21350 | } |
| 21363 | | 21351 | |
| 21364 | if (any_aligned_fields) { | 21352 | if (!try sema.intFitsInType(field_alignment_val, align_ty, null)) { |
| 21365 | if (!try sema.intFitsInType(field_alignment_val, .u32, null)) { | 21353 | return sema.fail(block, src, "alignment must fit in '{f}'", .{align_ty.fmt(pt)}); |
| 21366 | return sema.fail(block, src, "alignment must fit in 'u32'", .{}); | 21354 | } |
| 21367 | } | 21355 | const byte_align = try field_alignment_val.toUnsignedIntSema(pt); |
| 21368 | | 21356 | if (layout == .@"packed") { |
| 21369 | const byte_align = try field_alignment_val.toUnsignedIntSema(pt); | 21357 | if (byte_align != 0) return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{}); |
| 21370 | if (byte_align == 0) { | 21358 | } else { |
| 21371 | if (layout != .@"packed") { | 21359 | struct_type.field_aligns.get(ip)[field_idx] = try sema.validateAlign(block, src, byte_align); |
| 21372 | struct_type.field_aligns.get(ip)[field_idx] = .none; | | |
| 21373 | } | | |
| 21374 | } else { | | |
| 21375 | if (layout == .@"packed") return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{}); | | |
| 21376 | if (!math.isPowerOfTwo(byte_align)) return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align}); | | |
| 21377 | struct_type.field_aligns.get(ip)[field_idx] = Alignment.fromNonzeroByteUnits(byte_align); | | |
| 21378 | } | | |
| 21379 | } | 21360 | } |
| 21380 | | 21361 | |
| 21381 | const field_is_comptime = field_is_comptime_val.toBool(); | 21362 | const field_is_comptime = field_is_comptime_val.toBool(); |