Skip to content

Commit adc96eb

Browse files
committed
cbe: support rendering union values that have no defined tag type
This was regressed in d657b6c, when the comptime memory model for unions was changed to allow them to have no defined tag type.
1 parent 5e4a619 commit adc96eb

File tree

1 file changed

+71
-43
lines changed

1 file changed

+71
-43
lines changed

src/codegen/c.zig

Lines changed: 71 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,56 +1499,84 @@ pub const DeclGen = struct {
14991499
else => unreachable,
15001500
},
15011501
.un => |un| {
1502-
if (!location.isInitializer()) {
1503-
try writer.writeByte('(');
1504-
try dg.renderType(writer, ty);
1505-
try writer.writeByte(')');
1506-
}
1507-
15081502
const union_obj = mod.typeToUnion(ty).?;
1509-
const field_i = mod.unionTagFieldIndex(union_obj, un.tag.toValue()).?;
1510-
const field_ty = union_obj.field_types.get(ip)[field_i].toType();
1511-
const field_name = union_obj.field_names.get(ip)[field_i];
1512-
if (union_obj.getLayout(ip) == .Packed) {
1513-
if (field_ty.hasRuntimeBits(mod)) {
1514-
if (field_ty.isPtrAtRuntime(mod)) {
1515-
try writer.writeByte('(');
1516-
try dg.renderType(writer, ty);
1517-
try writer.writeByte(')');
1518-
} else if (field_ty.zigTypeTag(mod) == .Float) {
1519-
try writer.writeByte('(');
1503+
if (un.tag == .none) {
1504+
const backing_ty = try ty.unionBackingType(mod);
1505+
switch (union_obj.getLayout(ip)) {
1506+
.Packed => {
1507+
if (!location.isInitializer()) {
1508+
try writer.writeByte('(');
1509+
try dg.renderType(writer, backing_ty);
1510+
try writer.writeByte(')');
1511+
}
1512+
try dg.renderValue(writer, backing_ty, un.val.toValue(), initializer_type);
1513+
},
1514+
.Extern => {
1515+
if (location == .StaticInitializer) {
1516+
return dg.fail("TODO: C backend: implement extern union backing type rendering in static initializers", .{});
1517+
}
1518+
1519+
try writer.writeAll("*((");
15201520
try dg.renderType(writer, ty);
1521-
try writer.writeByte(')');
1521+
try writer.writeAll("*)(");
1522+
try dg.renderType(writer, backing_ty);
1523+
try writer.writeAll("){");
1524+
try dg.renderValue(writer, backing_ty, un.val.toValue(), initializer_type);
1525+
try writer.writeAll("})");
1526+
},
1527+
else => unreachable,
1528+
}
1529+
} else {
1530+
if (!location.isInitializer()) {
1531+
try writer.writeByte('(');
1532+
try dg.renderType(writer, ty);
1533+
try writer.writeByte(')');
1534+
}
1535+
1536+
const field_i = mod.unionTagFieldIndex(union_obj, un.tag.toValue()).?;
1537+
const field_ty = union_obj.field_types.get(ip)[field_i].toType();
1538+
const field_name = union_obj.field_names.get(ip)[field_i];
1539+
if (union_obj.getLayout(ip) == .Packed) {
1540+
if (field_ty.hasRuntimeBits(mod)) {
1541+
if (field_ty.isPtrAtRuntime(mod)) {
1542+
try writer.writeByte('(');
1543+
try dg.renderType(writer, ty);
1544+
try writer.writeByte(')');
1545+
} else if (field_ty.zigTypeTag(mod) == .Float) {
1546+
try writer.writeByte('(');
1547+
try dg.renderType(writer, ty);
1548+
try writer.writeByte(')');
1549+
}
1550+
try dg.renderValue(writer, field_ty, un.val.toValue(), initializer_type);
1551+
} else {
1552+
try writer.writeAll("0");
15221553
}
1523-
try dg.renderValue(writer, field_ty, un.val.toValue(), initializer_type);
1524-
} else {
1525-
try writer.writeAll("0");
1554+
return;
15261555
}
1527-
return;
1528-
}
15291556

1530-
try writer.writeByte('{');
1531-
if (ty.unionTagTypeSafety(mod)) |tag_ty| {
1532-
const layout = mod.getUnionLayout(union_obj);
1533-
if (layout.tag_size != 0) {
1534-
try writer.writeAll(" .tag = ");
1535-
try dg.renderValue(writer, tag_ty, un.tag.toValue(), initializer_type);
1557+
try writer.writeByte('{');
1558+
if (ty.unionTagTypeSafety(mod)) |tag_ty| {
1559+
const layout = mod.getUnionLayout(union_obj);
1560+
if (layout.tag_size != 0) {
1561+
try writer.writeAll(" .tag = ");
1562+
try dg.renderValue(writer, tag_ty, un.tag.toValue(), initializer_type);
1563+
}
1564+
if (ty.unionHasAllZeroBitFieldTypes(mod)) return try writer.writeByte('}');
1565+
if (layout.tag_size != 0) try writer.writeByte(',');
1566+
try writer.writeAll(" .payload = {");
15361567
}
1537-
if (ty.unionHasAllZeroBitFieldTypes(mod)) return try writer.writeByte('}');
1538-
if (layout.tag_size != 0) try writer.writeByte(',');
1539-
try writer.writeAll(" .payload = {");
1540-
}
1541-
if (field_ty.hasRuntimeBits(mod)) {
1542-
try writer.print(" .{ } = ", .{fmtIdent(ip.stringToSlice(field_name))});
1543-
try dg.renderValue(writer, field_ty, un.val.toValue(), initializer_type);
1544-
try writer.writeByte(' ');
1545-
} else for (union_obj.field_types.get(ip)) |this_field_ty| {
1546-
if (!this_field_ty.toType().hasRuntimeBits(mod)) continue;
1547-
try dg.renderValue(writer, this_field_ty.toType(), Value.undef, initializer_type);
1548-
break;
1568+
if (field_ty.hasRuntimeBits(mod)) {
1569+
try writer.print(" .{ } = ", .{fmtIdent(ip.stringToSlice(field_name))});
1570+
try dg.renderValue(writer, field_ty, un.val.toValue(), initializer_type);
1571+
try writer.writeByte(' ');
1572+
} else for (union_obj.field_types.get(ip)) |this_field_ty| {
1573+
if (!this_field_ty.toType().hasRuntimeBits(mod)) continue;
1574+
try dg.renderValue(writer, this_field_ty.toType(), Value.undef, initializer_type);
1575+
break;
1576+
}
1577+
if (ty.unionTagTypeSafety(mod)) |_| try writer.writeByte('}');
1578+
try writer.writeByte('}');
15491579
}
1550-
if (ty.unionTagTypeSafety(mod)) |_| try writer.writeByte('}');
1551-
try writer.writeByte('}');
15521580
},
15531581
}
15541582
}

0 commit comments

Comments
 (0)