| author | |
| committer | |
| log | c80aa9f71960ed90787033293fbc4c6ccfe0fba8 |
| tree | 84d5df492d5a0f6c3c31370ed97c6e58e1c14c40 |
| parent | 616e69c80745cdc872b1db5ad63b919d82d9e9cb |
| parent | e82d67233b615e04fb5e4f31cd93216a2c1c2899 |
| signature |
sema: compile error on reifying align(0) fields and pointers15 files changed, 147 insertions(+), 129 deletions(-)
lib/compiler/aro/aro/Attribute.zig+1-1| ... | ... | @@ -708,7 +708,7 @@ pub const Arguments = blk: { |
| 708 | 708 | field.* = .{ |
| 709 | 709 | .name = decl.name, |
| 710 | 710 | .type = @field(attributes, decl.name), |
| 711 | .alignment = 0, | |
| 711 | .alignment = @alignOf(@field(attributes, decl.name)), | |
| 712 | 712 | }; |
| 713 | 713 | } |
| 714 | 714 |
lib/std/meta.zig+1-1| ... | ... | @@ -939,7 +939,7 @@ fn CreateUniqueTuple(comptime N: comptime_int, comptime types: [N]type) type { |
| 939 | 939 | .type = T, |
| 940 | 940 | .default_value_ptr = null, |
| 941 | 941 | .is_comptime = false, |
| 942 | .alignment = 0, | |
| 942 | .alignment = @alignOf(T), | |
| 943 | 943 | }; |
| 944 | 944 | } |
| 945 | 945 |
lib/std/zig/AstGen.zig+3| ... | ... | @@ -5386,6 +5386,9 @@ fn unionDeclInner( |
| 5386 | 5386 | return astgen.failNode(member_node, "union field missing type", .{}); |
| 5387 | 5387 | } |
| 5388 | 5388 | if (member.ast.align_expr.unwrap()) |align_expr| { |
| 5389 | if (layout == .@"packed") { | |
| 5390 | return astgen.failNode(align_expr, "unable to override alignment of packed union fields", .{}); | |
| 5391 | } | |
| 5389 | 5392 | const align_inst = try expr(&block_scope, &block_scope.base, coerced_align_ri, align_expr); |
| 5390 | 5393 | wip_members.appendToField(@intFromEnum(align_inst)); |
| 5391 | 5394 | any_aligned_fields = true; |
lib/std/zig/llvm/Builder.zig+4-3| ... | ... | @@ -8533,18 +8533,19 @@ pub const Metadata = enum(u32) { |
| 8533 | 8533 | .type = []const u8, |
| 8534 | 8534 | .default_value_ptr = null, |
| 8535 | 8535 | .is_comptime = false, |
| 8536 | .alignment = 0, | |
| 8536 | .alignment = @alignOf([]const u8), | |
| 8537 | 8537 | }; |
| 8538 | 8538 | } |
| 8539 | 8539 | fmt_str = fmt_str ++ "("; |
| 8540 | 8540 | inline for (fields[2..], names) |*field, name| { |
| 8541 | 8541 | fmt_str = fmt_str ++ "{[" ++ name ++ "]f}"; |
| 8542 | const T = std.fmt.Formatter(FormatData, format); | |
| 8542 | 8543 | field.* = .{ |
| 8543 | 8544 | .name = name, |
| 8544 | .type = std.fmt.Formatter(FormatData, format), | |
| 8545 | .type = T, | |
| 8545 | 8546 | .default_value_ptr = null, |
| 8546 | 8547 | .is_comptime = false, |
| 8547 | .alignment = 0, | |
| 8548 | .alignment = @alignOf(T), | |
| 8548 | 8549 | }; |
| 8549 | 8550 | } |
| 8550 | 8551 | fmt_str = fmt_str ++ ")\n"; |
src/InternPool.zig+22-16| ... | ... | @@ -1137,13 +1137,16 @@ const Local = struct { |
| 1137 | 1137 | const elem_info = @typeInfo(Elem).@"struct"; |
| 1138 | 1138 | const elem_fields = elem_info.fields; |
| 1139 | 1139 | var new_fields: [elem_fields.len]std.builtin.Type.StructField = undefined; |
| 1140 | for (&new_fields, elem_fields) |*new_field, elem_field| new_field.* = .{ | |
| 1141 | .name = elem_field.name, | |
| 1142 | .type = *[len]elem_field.type, | |
| 1143 | .default_value_ptr = null, | |
| 1144 | .is_comptime = false, | |
| 1145 | .alignment = 0, | |
| 1146 | }; | |
| 1140 | for (&new_fields, elem_fields) |*new_field, elem_field| { | |
| 1141 | const T = *[len]elem_field.type; | |
| 1142 | new_field.* = .{ | |
| 1143 | .name = elem_field.name, | |
| 1144 | .type = T, | |
| 1145 | .default_value_ptr = null, | |
| 1146 | .is_comptime = false, | |
| 1147 | .alignment = @alignOf(T), | |
| 1148 | }; | |
| 1149 | } | |
| 1147 | 1150 | return @Type(.{ .@"struct" = .{ |
| 1148 | 1151 | .layout = .auto, |
| 1149 | 1152 | .fields = &new_fields, |
| ... | ... | @@ -1158,22 +1161,25 @@ const Local = struct { |
| 1158 | 1161 | const elem_info = @typeInfo(Elem).@"struct"; |
| 1159 | 1162 | const elem_fields = elem_info.fields; |
| 1160 | 1163 | var new_fields: [elem_fields.len]std.builtin.Type.StructField = undefined; |
| 1161 | for (&new_fields, elem_fields) |*new_field, elem_field| new_field.* = .{ | |
| 1162 | .name = elem_field.name, | |
| 1163 | .type = @Type(.{ .pointer = .{ | |
| 1164 | for (&new_fields, elem_fields) |*new_field, elem_field| { | |
| 1165 | const T = @Type(.{ .pointer = .{ | |
| 1164 | 1166 | .size = opts.size, |
| 1165 | 1167 | .is_const = opts.is_const, |
| 1166 | 1168 | .is_volatile = false, |
| 1167 | .alignment = 0, | |
| 1169 | .alignment = @alignOf(elem_field.type), | |
| 1168 | 1170 | .address_space = .generic, |
| 1169 | 1171 | .child = elem_field.type, |
| 1170 | 1172 | .is_allowzero = false, |
| 1171 | 1173 | .sentinel_ptr = null, |
| 1172 | } }), | |
| 1173 | .default_value_ptr = null, | |
| 1174 | .is_comptime = false, | |
| 1175 | .alignment = 0, | |
| 1176 | }; | |
| 1174 | } }); | |
| 1175 | new_field.* = .{ | |
| 1176 | .name = elem_field.name, | |
| 1177 | .type = T, | |
| 1178 | .default_value_ptr = null, | |
| 1179 | .is_comptime = false, | |
| 1180 | .alignment = @alignOf(T), | |
| 1181 | }; | |
| 1182 | } | |
| 1177 | 1183 | return @Type(.{ .@"struct" = .{ |
| 1178 | 1184 | .layout = .auto, |
| 1179 | 1185 | .fields = &new_fields, |
src/Sema.zig+39-65| ... | ... | @@ -2649,7 +2649,13 @@ pub fn analyzeAsAlign( |
| 2649 | 2649 | src: LazySrcLoc, |
| 2650 | 2650 | air_ref: Air.Inst.Ref, |
| 2651 | 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 | 2659 | return sema.validateAlign(block, src, alignment_big); |
| 2654 | 2660 | } |
| 2655 | 2661 | |
| ... | ... | @@ -18817,7 +18823,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 18817 | 18823 | const abi_align: Alignment = if (inst_data.flags.has_align) blk: { |
| 18818 | 18824 | const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]); |
| 18819 | 18825 | extra_i += 1; |
| 18820 | const coerced = try sema.coerce(block, .u32, try sema.resolveInst(ref), align_src); | |
| 18826 | const coerced = try sema.coerce(block, align_ty, try sema.resolveInst(ref), align_src); | |
| 18821 | 18827 | const val = try sema.resolveConstDefinedValue(block, align_src, coerced, .{ .simple = .@"align" }); |
| 18822 | 18828 | // Check if this happens to be the lazy alignment of our element type, in |
| 18823 | 18829 | // which case we can make this 0 without resolving it. |
| ... | ... | @@ -20335,15 +20341,11 @@ fn zirReify( |
| 20335 | 20341 | try ip.getOrPutString(gpa, pt.tid, "sentinel_ptr", .no_embedded_nulls), |
| 20336 | 20342 | ).?); |
| 20337 | 20343 | |
| 20338 | if (!try sema.intFitsInType(alignment_val, .u32, null)) { | |
| 20339 | return sema.fail(block, src, "alignment must fit in 'u32'", .{}); | |
| 20344 | if (!try sema.intFitsInType(alignment_val, align_ty, null)) { | |
| 20345 | return sema.fail(block, src, "alignment must fit in '{f}'", .{align_ty.fmt(pt)}); | |
| 20340 | 20346 | } |
| 20341 | ||
| 20342 | 20347 | const alignment_val_int = try alignment_val.toUnsignedIntSema(pt); |
| 20343 | if (alignment_val_int > 0 and !math.isPowerOfTwo(alignment_val_int)) { | |
| 20344 | return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{alignment_val_int}); | |
| 20345 | } | |
| 20346 | const abi_align = Alignment.fromByteUnits(alignment_val_int); | |
| 20348 | const abi_align = try sema.validateAlign(block, src, alignment_val_int); | |
| 20347 | 20349 | |
| 20348 | 20350 | const elem_ty = child_val.toType(); |
| 20349 | 20351 | if (abi_align != .none) { |
| ... | ... | @@ -20920,8 +20922,6 @@ fn reifyUnion( |
| 20920 | 20922 | std.hash.autoHash(&hasher, opt_tag_type_val.toIntern()); |
| 20921 | 20923 | std.hash.autoHash(&hasher, fields_len); |
| 20922 | 20924 | |
| 20923 | var any_aligns = false; | |
| 20924 | ||
| 20925 | 20925 | for (0..fields_len) |field_idx| { |
| 20926 | 20926 | const field_info = try fields_val.elemValue(pt, field_idx); |
| 20927 | 20927 | |
| ... | ... | @@ -20930,16 +20930,11 @@ fn reifyUnion( |
| 20930 | 20930 | const field_align_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 2)); |
| 20931 | 20931 | |
| 20932 | 20932 | const field_name = try sema.sliceToIpString(block, src, field_name_val, .{ .simple = .union_field_name }); |
| 20933 | ||
| 20934 | 20933 | std.hash.autoHash(&hasher, .{ |
| 20935 | 20934 | field_name, |
| 20936 | 20935 | field_type_val.toIntern(), |
| 20937 | 20936 | field_align_val.toIntern(), |
| 20938 | 20937 | }); |
| 20939 | ||
| 20940 | if (field_align_val.toUnsignedInt(zcu) != 0) { | |
| 20941 | any_aligns = true; | |
| 20942 | } | |
| 20943 | 20938 | } |
| 20944 | 20939 | |
| 20945 | 20940 | const tracked_inst = try block.trackZir(inst); |
| ... | ... | @@ -20956,7 +20951,7 @@ fn reifyUnion( |
| 20956 | 20951 | true => .safety, |
| 20957 | 20952 | false => .none, |
| 20958 | 20953 | }, |
| 20959 | .any_aligned_fields = any_aligns, | |
| 20954 | .any_aligned_fields = layout != .@"packed", | |
| 20960 | 20955 | .requires_comptime = .unknown, |
| 20961 | 20956 | .assumed_runtime_bits = false, |
| 20962 | 20957 | .assumed_pointer_aligned = false, |
| ... | ... | @@ -20989,8 +20984,7 @@ fn reifyUnion( |
| 20989 | 20984 | ); |
| 20990 | 20985 | wip_ty.setName(ip, type_name.name, type_name.nav); |
| 20991 | 20986 | |
| 20992 | const field_types = try sema.arena.alloc(InternPool.Index, fields_len); | |
| 20993 | const field_aligns = if (any_aligns) try sema.arena.alloc(InternPool.Alignment, fields_len) else undefined; | |
| 20987 | const loaded_union = ip.loadUnionType(wip_ty.index); | |
| 20994 | 20988 | |
| 20995 | 20989 | const enum_tag_ty, const has_explicit_tag = if (opt_tag_type_val.optionalValue(zcu)) |tag_type_val| tag_ty: { |
| 20996 | 20990 | switch (ip.indexToKey(tag_type_val.toIntern())) { |
| ... | ... | @@ -21003,11 +20997,12 @@ fn reifyUnion( |
| 21003 | 20997 | const tag_ty_fields_len = enum_tag_ty.enumFieldCount(zcu); |
| 21004 | 20998 | var seen_tags = try std.DynamicBitSetUnmanaged.initEmpty(sema.arena, tag_ty_fields_len); |
| 21005 | 20999 | |
| 21006 | for (field_types, 0..) |*field_ty, field_idx| { | |
| 21000 | for (0..fields_len) |field_idx| { | |
| 21007 | 21001 | const field_info = try fields_val.elemValue(pt, field_idx); |
| 21008 | 21002 | |
| 21009 | 21003 | const field_name_val = try field_info.fieldValue(pt, 0); |
| 21010 | 21004 | const field_type_val = try field_info.fieldValue(pt, 1); |
| 21005 | const field_alignment_val = try field_info.fieldValue(pt, 2); | |
| 21011 | 21006 | |
| 21012 | 21007 | // Don't pass a reason; first loop acts as an assertion that this is valid. |
| 21013 | 21008 | const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined); |
| ... | ... | @@ -21024,14 +21019,12 @@ fn reifyUnion( |
| 21024 | 21019 | } |
| 21025 | 21020 | seen_tags.set(enum_index); |
| 21026 | 21021 | |
| 21027 | field_ty.* = field_type_val.toIntern(); | |
| 21028 | if (any_aligns) { | |
| 21029 | const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt); | |
| 21030 | if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) { | |
| 21031 | // TODO: better source location | |
| 21032 | return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align}); | |
| 21033 | } | |
| 21034 | field_aligns[field_idx] = Alignment.fromByteUnits(byte_align); | |
| 21022 | loaded_union.field_types.get(ip)[field_idx] = field_type_val.toIntern(); | |
| 21023 | const byte_align = try field_alignment_val.toUnsignedIntSema(pt); | |
| 21024 | if (layout == .@"packed") { | |
| 21025 | if (byte_align != 0) return sema.fail(block, src, "alignment of a packed union field must be set to 0", .{}); | |
| 21026 | } else { | |
| 21027 | loaded_union.field_aligns.get(ip)[field_idx] = try sema.validateAlign(block, src, byte_align); | |
| 21035 | 21028 | } |
| 21036 | 21029 | } |
| 21037 | 21030 | |
| ... | ... | @@ -21055,11 +21048,12 @@ fn reifyUnion( |
| 21055 | 21048 | var field_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void) = .empty; |
| 21056 | 21049 | try field_names.ensureTotalCapacity(sema.arena, fields_len); |
| 21057 | 21050 | |
| 21058 | for (field_types, 0..) |*field_ty, field_idx| { | |
| 21051 | for (0..fields_len) |field_idx| { | |
| 21059 | 21052 | const field_info = try fields_val.elemValue(pt, field_idx); |
| 21060 | 21053 | |
| 21061 | 21054 | const field_name_val = try field_info.fieldValue(pt, 0); |
| 21062 | 21055 | const field_type_val = try field_info.fieldValue(pt, 1); |
| 21056 | const field_alignment_val = try field_info.fieldValue(pt, 2); | |
| 21063 | 21057 | |
| 21064 | 21058 | // Don't pass a reason; first loop acts as an assertion that this is valid. |
| 21065 | 21059 | const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined); |
| ... | ... | @@ -21069,14 +21063,12 @@ fn reifyUnion( |
| 21069 | 21063 | return sema.fail(block, src, "duplicate union field {f}", .{field_name.fmt(ip)}); |
| 21070 | 21064 | } |
| 21071 | 21065 | |
| 21072 | field_ty.* = field_type_val.toIntern(); | |
| 21073 | if (any_aligns) { | |
| 21074 | const byte_align = try (try field_info.fieldValue(pt, 2)).toUnsignedIntSema(pt); | |
| 21075 | if (byte_align > 0 and !math.isPowerOfTwo(byte_align)) { | |
| 21076 | // TODO: better source location | |
| 21077 | return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align}); | |
| 21078 | } | |
| 21079 | field_aligns[field_idx] = Alignment.fromByteUnits(byte_align); | |
| 21066 | loaded_union.field_types.get(ip)[field_idx] = field_type_val.toIntern(); | |
| 21067 | const byte_align = try field_alignment_val.toUnsignedIntSema(pt); | |
| 21068 | if (layout == .@"packed") { | |
| 21069 | if (byte_align != 0) return sema.fail(block, src, "alignment of a packed union field must be set to 0", .{}); | |
| 21070 | } else { | |
| 21071 | loaded_union.field_aligns.get(ip)[field_idx] = try sema.validateAlign(block, src, byte_align); | |
| 21080 | 21072 | } |
| 21081 | 21073 | } |
| 21082 | 21074 | |
| ... | ... | @@ -21085,7 +21077,7 @@ fn reifyUnion( |
| 21085 | 21077 | }; |
| 21086 | 21078 | errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error |
| 21087 | 21079 | |
| 21088 | for (field_types) |field_ty_ip| { | |
| 21080 | for (loaded_union.field_types.get(ip)) |field_ty_ip| { | |
| 21089 | 21081 | const field_ty: Type = .fromInterned(field_ty_ip); |
| 21090 | 21082 | if (field_ty.zigTypeTag(zcu) == .@"opaque") { |
| 21091 | 21083 | return sema.failWithOwnedErrorMsg(block, msg: { |
| ... | ... | @@ -21119,11 +21111,6 @@ fn reifyUnion( |
| 21119 | 21111 | } |
| 21120 | 21112 | } |
| 21121 | 21113 | |
| 21122 | const loaded_union = ip.loadUnionType(wip_ty.index); | |
| 21123 | loaded_union.setFieldTypes(ip, field_types); | |
| 21124 | if (any_aligns) { | |
| 21125 | loaded_union.setFieldAligns(ip, field_aligns); | |
| 21126 | } | |
| 21127 | 21114 | loaded_union.setTagType(ip, enum_tag_ty); |
| 21128 | 21115 | loaded_union.setStatus(ip, .have_field_types); |
| 21129 | 21116 | |
| ... | ... | @@ -21276,7 +21263,6 @@ fn reifyStruct( |
| 21276 | 21263 | |
| 21277 | 21264 | var any_comptime_fields = false; |
| 21278 | 21265 | var any_default_inits = false; |
| 21279 | var any_aligned_fields = false; | |
| 21280 | 21266 | |
| 21281 | 21267 | for (0..fields_len) |field_idx| { |
| 21282 | 21268 | const field_info = try fields_val.elemValue(pt, field_idx); |
| ... | ... | @@ -21311,11 +21297,6 @@ fn reifyStruct( |
| 21311 | 21297 | |
| 21312 | 21298 | if (field_is_comptime) any_comptime_fields = true; |
| 21313 | 21299 | if (field_default_value != .none) any_default_inits = true; |
| 21314 | switch (try field_alignment_val.orderAgainstZeroSema(pt)) { | |
| 21315 | .eq => {}, | |
| 21316 | .gt => any_aligned_fields = true, | |
| 21317 | .lt => unreachable, | |
| 21318 | } | |
| 21319 | 21300 | } |
| 21320 | 21301 | |
| 21321 | 21302 | const tracked_inst = try block.trackZir(inst); |
| ... | ... | @@ -21327,7 +21308,7 @@ fn reifyStruct( |
| 21327 | 21308 | .requires_comptime = .unknown, |
| 21328 | 21309 | .any_comptime_fields = any_comptime_fields, |
| 21329 | 21310 | .any_default_inits = any_default_inits, |
| 21330 | .any_aligned_fields = any_aligned_fields, | |
| 21311 | .any_aligned_fields = layout != .@"packed", | |
| 21331 | 21312 | .inits_resolved = true, |
| 21332 | 21313 | .key = .{ .reified = .{ |
| 21333 | 21314 | .zir_index = tracked_inst, |
| ... | ... | @@ -21371,21 +21352,14 @@ fn reifyStruct( |
| 21371 | 21352 | return sema.fail(block, src, "duplicate struct field name {f}", .{field_name.fmt(ip)}); |
| 21372 | 21353 | } |
| 21373 | 21354 | |
| 21374 | if (any_aligned_fields) { | |
| 21375 | if (!try sema.intFitsInType(field_alignment_val, .u32, null)) { | |
| 21376 | return sema.fail(block, src, "alignment must fit in 'u32'", .{}); | |
| 21377 | } | |
| 21378 | ||
| 21379 | const byte_align = try field_alignment_val.toUnsignedIntSema(pt); | |
| 21380 | if (byte_align == 0) { | |
| 21381 | if (layout != .@"packed") { | |
| 21382 | struct_type.field_aligns.get(ip)[field_idx] = .none; | |
| 21383 | } | |
| 21384 | } else { | |
| 21385 | if (layout == .@"packed") return sema.fail(block, src, "alignment in a packed struct field must be set to 0", .{}); | |
| 21386 | if (!math.isPowerOfTwo(byte_align)) return sema.fail(block, src, "alignment value '{d}' is not a power of two or zero", .{byte_align}); | |
| 21387 | struct_type.field_aligns.get(ip)[field_idx] = Alignment.fromNonzeroByteUnits(byte_align); | |
| 21388 | } | |
| 21355 | if (!try sema.intFitsInType(field_alignment_val, align_ty, null)) { | |
| 21356 | return sema.fail(block, src, "alignment must fit in '{f}'", .{align_ty.fmt(pt)}); | |
| 21357 | } | |
| 21358 | const byte_align = try field_alignment_val.toUnsignedIntSema(pt); | |
| 21359 | if (layout == .@"packed") { | |
| 21360 | if (byte_align != 0) return sema.fail(block, src, "alignment of a packed struct field must be set to 0", .{}); | |
| 21361 | } else { | |
| 21362 | struct_type.field_aligns.get(ip)[field_idx] = try sema.validateAlign(block, src, byte_align); | |
| 21389 | 21363 | } |
| 21390 | 21364 | |
| 21391 | 21365 | const field_is_comptime = field_is_comptime_val.toBool(); |
src/codegen/aarch64/Assemble.zig+10-7| ... | ... | @@ -33,13 +33,16 @@ pub fn nextInstruction(as: *Assemble) !?Instruction { |
| 33 | 33 | var symbols: Symbols: { |
| 34 | 34 | const symbols = @typeInfo(@TypeOf(instruction.symbols)).@"struct".fields; |
| 35 | 35 | var symbol_fields: [symbols.len]std.builtin.Type.StructField = undefined; |
| 36 | for (&symbol_fields, symbols) |*symbol_field, symbol| symbol_field.* = .{ | |
| 37 | .name = symbol.name, | |
| 38 | .type = zonCast(SymbolSpec, @field(instruction.symbols, symbol.name), .{}).Storage(), | |
| 39 | .default_value_ptr = null, | |
| 40 | .is_comptime = false, | |
| 41 | .alignment = 0, | |
| 42 | }; | |
| 36 | for (&symbol_fields, symbols) |*symbol_field, symbol| { | |
| 37 | const Storage = zonCast(SymbolSpec, @field(instruction.symbols, symbol.name), .{}).Storage(); | |
| 38 | symbol_field.* = .{ | |
| 39 | .name = symbol.name, | |
| 40 | .type = Storage, | |
| 41 | .default_value_ptr = null, | |
| 42 | .is_comptime = false, | |
| 43 | .alignment = @alignOf(Storage), | |
| 44 | }; | |
| 45 | } | |
| 43 | 46 | break :Symbols @Type(.{ .@"struct" = .{ |
| 44 | 47 | .layout = .auto, |
| 45 | 48 | .fields = &symbol_fields, |
test/behavior/tuple.zig+4-2| ... | ... | @@ -318,6 +318,8 @@ test "tuple type with void field" { |
| 318 | 318 | test "zero sized struct in tuple handled correctly" { |
| 319 | 319 | const State = struct { |
| 320 | 320 | const Self = @This(); |
| 321 | const Inner = struct {}; | |
| 322 | ||
| 321 | 323 | data: @Type(.{ |
| 322 | 324 | .@"struct" = .{ |
| 323 | 325 | .is_tuple = true, |
| ... | ... | @@ -325,10 +327,10 @@ test "zero sized struct in tuple handled correctly" { |
| 325 | 327 | .decls = &.{}, |
| 326 | 328 | .fields = &.{.{ |
| 327 | 329 | .name = "0", |
| 328 | .type = struct {}, | |
| 330 | .type = Inner, | |
| 329 | 331 | .default_value_ptr = null, |
| 330 | 332 | .is_comptime = false, |
| 331 | .alignment = 0, | |
| 333 | .alignment = @alignOf(Inner), | |
| 332 | 334 | }}, |
| 333 | 335 | }, |
| 334 | 336 | }), |
test/behavior/type.zig+3-3| ... | ... | @@ -433,8 +433,8 @@ test "Type.Union" { |
| 433 | 433 | .layout = .@"packed", |
| 434 | 434 | .tag_type = null, |
| 435 | 435 | .fields = &.{ |
| 436 | .{ .name = "signed", .type = i32, .alignment = @alignOf(i32) }, | |
| 437 | .{ .name = "unsigned", .type = u32, .alignment = @alignOf(u32) }, | |
| 436 | .{ .name = "signed", .type = i32, .alignment = 0 }, | |
| 437 | .{ .name = "unsigned", .type = u32, .alignment = 0 }, | |
| 438 | 438 | }, |
| 439 | 439 | .decls = &.{}, |
| 440 | 440 | }, |
| ... | ... | @@ -735,7 +735,7 @@ test "struct field names sliced at comptime from larger string" { |
| 735 | 735 | var it = std.mem.tokenizeScalar(u8, text, '\n'); |
| 736 | 736 | while (it.next()) |name| { |
| 737 | 737 | fields = fields ++ &[_]Type.StructField{.{ |
| 738 | .alignment = 0, | |
| 738 | .alignment = @alignOf(usize), | |
| 739 | 739 | .name = name ++ "", |
| 740 | 740 | .type = usize, |
| 741 | 741 | .default_value_ptr = null, |
test/cases/compile_errors/align_zero.zig+44-16| ... | ... | @@ -1,52 +1,80 @@ |
| 1 | pub var global_var: i32 align(0) = undefined; | |
| 1 | var global_var: i32 align(0) = undefined; | |
| 2 | 2 | |
| 3 | pub export fn a() void { | |
| 3 | export fn a() void { | |
| 4 | 4 | _ = &global_var; |
| 5 | 5 | } |
| 6 | 6 | |
| 7 | pub extern var extern_var: i32 align(0); | |
| 7 | extern var extern_var: i32 align(0); | |
| 8 | 8 | |
| 9 | pub export fn b() void { | |
| 9 | export fn b() void { | |
| 10 | 10 | _ = &extern_var; |
| 11 | 11 | } |
| 12 | 12 | |
| 13 | pub export fn c() align(0) void {} | |
| 13 | export fn c() align(0) void {} | |
| 14 | 14 | |
| 15 | pub export fn d() void { | |
| 15 | export fn d() void { | |
| 16 | 16 | _ = *align(0) fn () i32; |
| 17 | 17 | } |
| 18 | 18 | |
| 19 | pub export fn e() void { | |
| 19 | export fn e() void { | |
| 20 | 20 | var local_var: i32 align(0) = undefined; |
| 21 | 21 | _ = &local_var; |
| 22 | 22 | } |
| 23 | 23 | |
| 24 | pub export fn f() void { | |
| 24 | export fn f() void { | |
| 25 | 25 | _ = *align(0) i32; |
| 26 | 26 | } |
| 27 | 27 | |
| 28 | pub export fn g() void { | |
| 28 | export fn g() void { | |
| 29 | 29 | _ = []align(0) i32; |
| 30 | 30 | } |
| 31 | 31 | |
| 32 | pub export fn h() void { | |
| 32 | export fn h() void { | |
| 33 | 33 | _ = struct { field: i32 align(0) }; |
| 34 | 34 | } |
| 35 | 35 | |
| 36 | pub export fn i() void { | |
| 36 | export fn i() void { | |
| 37 | 37 | _ = union { field: i32 align(0) }; |
| 38 | 38 | } |
| 39 | 39 | |
| 40 | export fn j() void { | |
| 41 | _ = @Type(.{ .@"struct" = .{ | |
| 42 | .layout = .auto, | |
| 43 | .fields = &.{.{ | |
| 44 | .name = "test", | |
| 45 | .type = u32, | |
| 46 | .default_value_ptr = null, | |
| 47 | .is_comptime = false, | |
| 48 | .alignment = 0, | |
| 49 | }}, | |
| 50 | .decls = &.{}, | |
| 51 | .is_tuple = false, | |
| 52 | } }); | |
| 53 | } | |
| 54 | ||
| 55 | export fn k() void { | |
| 56 | _ = @Type(.{ .pointer = .{ | |
| 57 | .size = .one, | |
| 58 | .is_const = false, | |
| 59 | .is_volatile = false, | |
| 60 | .alignment = 0, | |
| 61 | .address_space = .generic, | |
| 62 | .child = u32, | |
| 63 | .is_allowzero = false, | |
| 64 | .sentinel_ptr = null, | |
| 65 | } }); | |
| 66 | } | |
| 67 | ||
| 40 | 68 | // error |
| 41 | // backend=stage2 | |
| 42 | // target=native | |
| 43 | 69 | // |
| 44 | // :1:31: error: alignment must be >= 1 | |
| 45 | // :7:38: error: alignment must be >= 1 | |
| 46 | // :13:25: error: alignment must be >= 1 | |
| 70 | // :1:27: error: alignment must be >= 1 | |
| 71 | // :7:34: error: alignment must be >= 1 | |
| 72 | // :13:21: error: alignment must be >= 1 | |
| 47 | 73 | // :16:16: error: alignment must be >= 1 |
| 48 | 74 | // :20:30: error: alignment must be >= 1 |
| 49 | 75 | // :25:16: error: alignment must be >= 1 |
| 50 | 76 | // :29:17: error: alignment must be >= 1 |
| 51 | 77 | // :33:35: error: alignment must be >= 1 |
| 52 | 78 | // :37:34: error: alignment must be >= 1 |
| 79 | // :41:9: error: alignment must be >= 1 | |
| 80 | // :56:9: error: alignment must be >= 1 |
test/cases/compile_errors/bad_alignment_type.zig+2-2| ... | ... | @@ -11,5 +11,5 @@ export fn entry2() void { |
| 11 | 11 | // backend=stage2 |
| 12 | 12 | // target=native |
| 13 | 13 | // |
| 14 | // :2:22: error: expected type 'u32', found 'bool' | |
| 15 | // :6:21: error: fractional component prevents float value '12.34' from coercion to type 'u32' | |
| 14 | // :2:22: error: expected type 'u29', found 'bool' | |
| 15 | // :6:21: error: fractional component prevents float value '12.34' from coercion to type 'u29' |
test/cases/compile_errors/packed_struct_field_alignment_unavailable_for_reify_type.zig deleted-9| ... | ... | @@ -1,9 +0,0 @@ |
| 1 | export fn entry() void { | |
| 2 | _ = @Type(.{ .@"struct" = .{ .layout = .@"packed", .fields = &.{ | |
| 3 | .{ .name = "one", .type = u4, .default_value_ptr = null, .is_comptime = false, .alignment = 2 }, | |
| 4 | }, .decls = &.{}, .is_tuple = false } }); | |
| 5 | } | |
| 6 | ||
| 7 | // error | |
| 8 | // | |
| 9 | // :2:9: error: alignment in a packed struct field must be set to 0 |
test/cases/compile_errors/packed_union_alignment_override.zig created+9| ... | ... | @@ -0,0 +1,9 @@ |
| 1 | const U = packed union { | |
| 2 | x: f32, | |
| 3 | y: u8 align(10), | |
| 4 | z: u32, | |
| 5 | }; | |
| 6 | ||
| 7 | // error | |
| 8 | // | |
| 9 | // :3:17: error: unable to override alignment of packed union fields |
test/cases/compile_errors/reify_struct.zig+2-1| ... | ... | @@ -75,4 +75,5 @@ comptime { |
| 75 | 75 | // :16:5: error: tuple field name '3' does not match field index 0 |
| 76 | 76 | // :30:5: error: comptime field without default initialization value |
| 77 | 77 | // :44:5: error: extern struct fields cannot be marked comptime |
| 78 | // :58:5: error: alignment in a packed struct field must be set to 0 | |
| 78 | // :58:5: error: alignment of a packed struct field must be set to 0 | |
| 79 |
test/cases/compile_errors/reify_type_with_invalid_field_alignment.zig+3-3| ... | ... | @@ -43,6 +43,6 @@ comptime { |
| 43 | 43 | |
| 44 | 44 | // error |
| 45 | 45 | // |
| 46 | // :2:9: error: alignment value '3' is not a power of two or zero | |
| 47 | // :14:9: error: alignment value '5' is not a power of two or zero | |
| 48 | // :30:9: error: alignment value '7' is not a power of two or zero | |
| 46 | // :2:9: error: alignment value '3' is not a power of two | |
| 47 | // :14:9: error: alignment value '5' is not a power of two | |
| 48 | // :30:9: error: alignment value '7' is not a power of two |