diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-09-21 17:29:34 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-09-21 17:29:34 -0700 |
| commit | 81b5df347a2b92566dc679fdd4e110812dfe27d0 (patch) | |
| tree | 2e2580b944374f490797ef3211eb752c7b1bc051 /src/codegen | |
| parent | edfada4317760a152ad9c36b39f5a2e68eeaebf8 (diff) | |
| download | zig-81b5df347a2b92566dc679fdd4e110812dfe27d0.tar.gz zig-81b5df347a2b92566dc679fdd4e110812dfe27d0.zip | |
compiler: fix structFieldName crash for tuples
When struct types have no field names, the names are implicitly
understood to be strings corresponding to the field indexes in
declaration order. It used to be the case that a NullTerminatedString
would be stored for each field in this case, however, now, callers must
handle the possibility that there are no names stored at all. This
commit introduces `legacyStructFieldName`, a function to fake the
previous behavior. Probably something better could be done by reworking
all the callsites of this function.
Diffstat (limited to 'src/codegen')
| -rw-r--r-- | src/codegen/c.zig | 14 | ||||
| -rw-r--r-- | src/codegen/c/type.zig | 15 |
2 files changed, 17 insertions, 12 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 7f3f1b795e..54e13db9a1 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -5226,7 +5226,8 @@ fn fieldLocation( const container_ty = container_ptr_ty.childType(mod); return switch (container_ty.zigTypeTag(mod)) { .Struct => switch (container_ty.containerLayout(mod)) { - .Auto, .Extern => for (field_index..container_ty.structFieldCount(mod)) |next_field_index| { + .Auto, .Extern => for (field_index..container_ty.structFieldCount(mod)) |next_field_index_usize| { + const next_field_index: u32 = @intCast(next_field_index_usize); if (container_ty.structFieldIsComptime(next_field_index, mod)) continue; const field_ty = container_ty.structFieldType(next_field_index, mod); if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue; @@ -5234,7 +5235,7 @@ fn fieldLocation( break .{ .field = if (container_ty.isSimpleTuple(mod)) .{ .field = next_field_index } else - .{ .identifier = ip.stringToSlice(container_ty.structFieldName(next_field_index, mod)) } }; + .{ .identifier = ip.stringToSlice(container_ty.legacyStructFieldName(next_field_index, mod)) } }; } else if (container_ty.hasRuntimeBitsIgnoreComptime(mod)) .end else .begin, .Packed => if (field_ptr_ty.ptrInfo(mod).packed_offset.host_size == 0) .{ .byte_offset = container_ty.packedStructFieldByteOffset(field_index, mod) + @divExact(container_ptr_ty.ptrInfo(mod).packed_offset.bit_offset, 8) } @@ -5421,7 +5422,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { .Auto, .Extern => if (struct_ty.isSimpleTuple(mod)) .{ .field = extra.field_index } else - .{ .identifier = ip.stringToSlice(struct_ty.structFieldName(extra.field_index, mod)) }, + .{ .identifier = ip.stringToSlice(struct_ty.legacyStructFieldName(extra.field_index, mod)) }, .Packed => { const struct_type = mod.typeToStruct(struct_ty).?; const int_info = struct_ty.intInfo(mod); @@ -5483,7 +5484,7 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len == 0) .{ .field = extra.field_index } else - .{ .identifier = ip.stringToSlice(struct_ty.structFieldName(extra.field_index, mod)) }, + .{ .identifier = ip.stringToSlice(struct_ty.legacyStructFieldName(extra.field_index, mod)) }, .union_type => |union_type| field_name: { const union_obj = ip.loadUnionType(union_type); @@ -6816,7 +6817,8 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { } }, .Struct => switch (inst_ty.containerLayout(mod)) { - .Auto, .Extern => for (resolved_elements, 0..) |element, field_i| { + .Auto, .Extern => for (resolved_elements, 0..) |element, field_i_usize| { + const field_i: u32 = @intCast(field_i_usize); if (inst_ty.structFieldIsComptime(field_i, mod)) continue; const field_ty = inst_ty.structFieldType(field_i, mod); if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue; @@ -6825,7 +6827,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { try f.writeCValueMember(writer, local, if (inst_ty.isSimpleTuple(mod)) .{ .field = field_i } else - .{ .identifier = ip.stringToSlice(inst_ty.structFieldName(field_i, mod)) }); + .{ .identifier = ip.stringToSlice(inst_ty.legacyStructFieldName(field_i, mod)) }); try a.assign(f, writer); try f.writeCValue(writer, element, .Other); try a.end(f, writer); diff --git a/src/codegen/c/type.zig b/src/codegen/c/type.zig index 731d2b6557..81cbe46768 100644 --- a/src/codegen/c/type.zig +++ b/src/codegen/c/type.zig @@ -1953,7 +1953,8 @@ pub const CType = extern union { const fields_pl = try arena.alloc(Payload.Fields.Field, c_fields_len); var c_field_i: usize = 0; - for (0..fields_len) |field_i| { + for (0..fields_len) |field_i_usize| { + const field_i: u32 = @intCast(field_i_usize); const field_ty = ty.structFieldType(field_i, mod); if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i, mod)) or !field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue; @@ -1964,7 +1965,7 @@ pub const CType = extern union { std.fmt.allocPrintZ(arena, "f{}", .{field_i}) else arena.dupeZ(u8, ip.stringToSlice(switch (zig_ty_tag) { - .Struct => ty.structFieldName(field_i, mod), + .Struct => ty.legacyStructFieldName(field_i, mod), .Union => mod.typeToUnion(ty).?.field_names.get(ip)[field_i], else => unreachable, })), @@ -2097,7 +2098,8 @@ pub const CType = extern union { .Struct => ty.structFieldCount(mod), .Union => mod.typeToUnion(ty).?.field_names.len, else => unreachable, - }) |field_i| { + }) |field_i_usize| { + const field_i: u32 = @intCast(field_i_usize); const field_ty = ty.structFieldType(field_i, mod); if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i, mod)) or !field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue; @@ -2116,7 +2118,7 @@ pub const CType = extern union { std.fmt.bufPrintZ(&name_buf, "f{}", .{field_i}) catch unreachable else ip.stringToSlice(switch (zig_ty_tag) { - .Struct => ty.structFieldName(field_i, mod), + .Struct => ty.legacyStructFieldName(field_i, mod), .Union => mod.typeToUnion(ty).?.field_names.get(ip)[field_i], else => unreachable, }), @@ -2225,7 +2227,8 @@ pub const CType = extern union { .Struct => ty.structFieldCount(mod), .Union => mod.typeToUnion(ty).?.field_names.len, else => unreachable, - }) |field_i| { + }) |field_i_usize| { + const field_i: u32 = @intCast(field_i_usize); const field_ty = ty.structFieldType(field_i, mod); if ((zig_ty_tag == .Struct and ty.structFieldIsComptime(field_i, mod)) or !field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue; @@ -2240,7 +2243,7 @@ pub const CType = extern union { std.fmt.bufPrint(&name_buf, "f{}", .{field_i}) catch unreachable else mod.intern_pool.stringToSlice(switch (zig_ty_tag) { - .Struct => ty.structFieldName(field_i, mod), + .Struct => ty.legacyStructFieldName(field_i, mod), .Union => mod.typeToUnion(ty).?.field_names.get(ip)[field_i], else => unreachable, })); |
