zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 35c86984a6c5e275c5c980ebb9d4b372291c9917 (tree)
parent f10499be0a16ec58d98387b49189401f2af2094f
Author: kcbanner <kcbanner@gmail.com>
Date:   Fri, 27 Oct 2023 01:30:04 -0400

cbe: support rendering union values that have no defined tag type

This was regressed in d657b6c0e2ab7c47f5416dc4df1abb2bfbecd4b6, when
the comptime memory model for unions was changed to allow them to have
no defined tag type.

Diffstat:
Msrc/codegen/c.zig | 117+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
1 file changed, 73 insertions(+), 44 deletions(-)

diff --git a/src/codegen/c.zig b/src/codegen/c.zig @@ -1499,56 +1499,85 @@ pub const DeclGen = struct { else => unreachable, }, .un => |un| { - if (!location.isInitializer()) { - try writer.writeByte('('); - try dg.renderType(writer, ty); - try writer.writeByte(')'); - } - const union_obj = mod.typeToUnion(ty).?; - const field_i = mod.unionTagFieldIndex(union_obj, un.tag.toValue()).?; - const field_ty = union_obj.field_types.get(ip)[field_i].toType(); - const field_name = union_obj.field_names.get(ip)[field_i]; - if (union_obj.getLayout(ip) == .Packed) { - if (field_ty.hasRuntimeBits(mod)) { - if (field_ty.isPtrAtRuntime(mod)) { - try writer.writeByte('('); - try dg.renderType(writer, ty); - try writer.writeByte(')'); - } else if (field_ty.zigTypeTag(mod) == .Float) { - try writer.writeByte('('); - try dg.renderType(writer, ty); - try writer.writeByte(')'); + if (un.tag == .none) { + const backing_ty = try ty.unionBackingType(mod); + switch (union_obj.getLayout(ip)) { + .Packed => { + if (!location.isInitializer()) { + try writer.writeByte('('); + try dg.renderType(writer, backing_ty); + try writer.writeByte(')'); + } + try dg.renderValue(writer, backing_ty, un.val.toValue(), initializer_type); + }, + .Extern => { + if (location == .StaticInitializer) { + return dg.fail("TODO: C backend: implement extern union backing type rendering in static initializers", .{}); + } + + const ptr_ty = try mod.singleConstPtrType(ty); + try writer.writeAll("*(("); + try dg.renderType(writer, ptr_ty); + try writer.writeAll(")("); + try dg.renderType(writer, backing_ty); + try writer.writeAll("){"); + try dg.renderValue(writer, backing_ty, un.val.toValue(), initializer_type); + try writer.writeAll("})"); + }, + else => unreachable, + } + } else { + if (!location.isInitializer()) { + try writer.writeByte('('); + try dg.renderType(writer, ty); + try writer.writeByte(')'); + } + + const field_i = mod.unionTagFieldIndex(union_obj, un.tag.toValue()).?; + const field_ty = union_obj.field_types.get(ip)[field_i].toType(); + const field_name = union_obj.field_names.get(ip)[field_i]; + if (union_obj.getLayout(ip) == .Packed) { + if (field_ty.hasRuntimeBits(mod)) { + if (field_ty.isPtrAtRuntime(mod)) { + try writer.writeByte('('); + try dg.renderType(writer, ty); + try writer.writeByte(')'); + } else if (field_ty.zigTypeTag(mod) == .Float) { + try writer.writeByte('('); + try dg.renderType(writer, ty); + try writer.writeByte(')'); + } + try dg.renderValue(writer, field_ty, un.val.toValue(), initializer_type); + } else { + try writer.writeAll("0"); } - try dg.renderValue(writer, field_ty, un.val.toValue(), initializer_type); - } else { - try writer.writeAll("0"); + return; } - return; - } - try writer.writeByte('{'); - if (ty.unionTagTypeSafety(mod)) |tag_ty| { - const layout = mod.getUnionLayout(union_obj); - if (layout.tag_size != 0) { - try writer.writeAll(" .tag = "); - try dg.renderValue(writer, tag_ty, un.tag.toValue(), initializer_type); + try writer.writeByte('{'); + if (ty.unionTagTypeSafety(mod)) |tag_ty| { + const layout = mod.getUnionLayout(union_obj); + if (layout.tag_size != 0) { + try writer.writeAll(" .tag = "); + try dg.renderValue(writer, tag_ty, un.tag.toValue(), initializer_type); + } + if (ty.unionHasAllZeroBitFieldTypes(mod)) return try writer.writeByte('}'); + if (layout.tag_size != 0) try writer.writeByte(','); + try writer.writeAll(" .payload = {"); } - if (ty.unionHasAllZeroBitFieldTypes(mod)) return try writer.writeByte('}'); - if (layout.tag_size != 0) try writer.writeByte(','); - try writer.writeAll(" .payload = {"); - } - if (field_ty.hasRuntimeBits(mod)) { - try writer.print(" .{ } = ", .{fmtIdent(ip.stringToSlice(field_name))}); - try dg.renderValue(writer, field_ty, un.val.toValue(), initializer_type); - try writer.writeByte(' '); - } else for (union_obj.field_types.get(ip)) |this_field_ty| { - if (!this_field_ty.toType().hasRuntimeBits(mod)) continue; - try dg.renderValue(writer, this_field_ty.toType(), Value.undef, initializer_type); - break; + if (field_ty.hasRuntimeBits(mod)) { + try writer.print(" .{ } = ", .{fmtIdent(ip.stringToSlice(field_name))}); + try dg.renderValue(writer, field_ty, un.val.toValue(), initializer_type); + try writer.writeByte(' '); + } else for (union_obj.field_types.get(ip)) |this_field_ty| { + if (!this_field_ty.toType().hasRuntimeBits(mod)) continue; + try dg.renderValue(writer, this_field_ty.toType(), Value.undef, initializer_type); + break; + } + if (ty.unionTagTypeSafety(mod)) |_| try writer.writeByte('}'); + try writer.writeByte('}'); } - if (ty.unionTagTypeSafety(mod)) |_| try writer.writeByte('}'); - try writer.writeByte('}'); }, } }