authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-03-29 20:18:09-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2024-03-30 20:50:48-04:00
logfb192df4f2d12dda5019e14bf6cab2693432cb36
tree4965e60a86a7d46b38f9618884153e5e6b0b5a2e
parent7580879e8bed9b0c670df110dbdaed76b2c3baf5

cbe: fix uncovered bugs


4 files changed, 102 insertions(+), 79 deletions(-)

lib/zig.h+7-11
......@@ -130,22 +130,18 @@ typedef char bool;
130130#define zig_restrict
131131#endif
132132
133#if __STDC_VERSION__ >= 201112L
134#define zig_align(alignment) _Alignas(alignment)
135#elif zig_has_attribute(aligned)
136#define zig_align(alignment) __attribute__((aligned(alignment)))
133#if zig_has_attribute(aligned)
134#define zig_under_align(alignment) __attribute__((aligned(alignment)))
137135#elif _MSC_VER
138#define zig_align(alignment) __declspec(align(alignment))
136#define zig_under_align(alignment) __declspec(align(alignment))
139137#else
140#define zig_align zig_align_unavailable
138#define zig_under_align zig_align_unavailable
141139#endif
142140
143#if zig_has_attribute(aligned)
144#define zig_under_align(alignment) __attribute__((aligned(alignment)))
145#elif _MSC_VER
146#define zig_under_align(alignment) zig_align(alignment)
141#if __STDC_VERSION__ >= 201112L
142#define zig_align(alignment) _Alignas(alignment)
147143#else
148#define zig_align zig_align_unavailable
144#define zig_align(alignment) zig_under_align(alignment)
149145#endif
150146
151147#if zig_has_attribute(aligned)
src/Sema.zig+5-2
......@@ -36125,7 +36125,7 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
3612536125 // alignment is greater.
3612636126 var size: u64 = 0;
3612736127 var padding: u32 = 0;
36128 if (tag_align.compare(.gte, max_align)) {
36128 if (tag_align.order(max_align).compare(.gte)) {
3612936129 // {Tag, Payload}
3613036130 size += tag_size;
3613136131 size = max_align.forward(size);
......@@ -36136,7 +36136,10 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
3613636136 } else {
3613736137 // {Payload, Tag}
3613836138 size += max_size;
36139 size = tag_align.forward(size);
36139 size = switch (mod.getTarget().ofmt) {
36140 .c => max_align,
36141 else => tag_align,
36142 }.forward(size);
3614036143 size += tag_size;
3614136144 const prev_size = size;
3614236145 size = max_align.forward(size);
src/codegen/c.zig+42-37
......@@ -2475,14 +2475,20 @@ pub fn genTypeDecl(
24752475 .basic, .pointer, .array, .vector, .function => {},
24762476 .aligned => |aligned_info| {
24772477 if (!found_existing) {
2478 try writer.writeAll("typedef ");
2479 try writer.print("{}", .{
2480 try renderTypePrefix(pass, global_ctype_pool, zcu, writer, aligned_info.ctype, .suffix, .{}),
2481 });
2482 try renderAlignedTypeName(writer, global_ctype);
2483 try renderTypeSuffix(pass, global_ctype_pool, zcu, writer, aligned_info.ctype, .suffix, .{});
24842478 std.debug.assert(aligned_info.alignas.abiOrder().compare(.lt));
2485 try writer.print(" zig_under_align({d});\n", .{aligned_info.alignas.toByteUnits()});
2479 try writer.print("typedef zig_under_align({d}) ", .{aligned_info.alignas.toByteUnits()});
2480 try writer.print("{}", .{try renderTypePrefix(
2481 .flush,
2482 global_ctype_pool,
2483 zcu,
2484 writer,
2485 aligned_info.ctype,
2486 .suffix,
2487 .{},
2488 )});
2489 try renderAlignedTypeName(writer, global_ctype);
2490 try renderTypeSuffix(.flush, global_ctype_pool, zcu, writer, aligned_info.ctype, .suffix, .{});
2491 try writer.writeAll(";\n");
24862492 }
24872493 switch (pass) {
24882494 .decl, .anon => {
......@@ -5032,15 +5038,18 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
50325038 const result = result: {
50335039 const writer = f.object.writer();
50345040 const inst_ty = f.typeOfIndex(inst);
5035 const local = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) local: {
5036 const local = try f.allocLocal(inst, inst_ty);
5041 const inst_local = if (inst_ty.hasRuntimeBitsIgnoreComptime(zcu)) local: {
5042 const inst_local = try f.allocLocalValue(.{
5043 .ctype = try f.ctypeFromType(inst_ty, .complete),
5044 .alignas = CType.AlignAs.fromAbiAlignment(inst_ty.abiAlignment(zcu)),
5045 });
50375046 if (f.wantSafety()) {
5038 try f.writeCValue(writer, local, .Other);
5047 try f.writeCValue(writer, inst_local, .Other);
50395048 try writer.writeAll(" = ");
50405049 try f.writeCValue(writer, .{ .undef = inst_ty }, .Other);
50415050 try writer.writeAll(";\n");
50425051 }
5043 break :local local;
5052 break :local inst_local;
50445053 } else .none;
50455054
50465055 const locals_begin = @as(LocalIndex, @intCast(f.locals.items.len));
......@@ -5063,9 +5072,12 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
50635072 if (is_reg) {
50645073 const output_ty = if (output == .none) inst_ty else f.typeOf(output).childType(zcu);
50655074 try writer.writeAll("register ");
5066 const local_value = try f.allocLocal(inst, output_ty);
5067 try f.allocs.put(gpa, local_value.new_local, false);
5068 try f.object.dg.renderTypeAndName(writer, output_ty, local_value, .{}, .none, .complete);
5075 const output_local = try f.allocLocalValue(.{
5076 .ctype = try f.ctypeFromType(output_ty, .complete),
5077 .alignas = CType.AlignAs.fromAbiAlignment(output_ty.abiAlignment(zcu)),
5078 });
5079 try f.allocs.put(gpa, output_local.new_local, false);
5080 try f.object.dg.renderTypeAndName(writer, output_ty, output_local, .{}, .none, .complete);
50695081 try writer.writeAll(" __asm(\"");
50705082 try writer.writeAll(constraint["={".len .. constraint.len - "}".len]);
50715083 try writer.writeAll("\")");
......@@ -5095,9 +5107,12 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
50955107 if (asmInputNeedsLocal(f, constraint, input_val)) {
50965108 const input_ty = f.typeOf(input);
50975109 if (is_reg) try writer.writeAll("register ");
5098 const local_value = try f.allocLocal(inst, input_ty);
5099 try f.allocs.put(gpa, local_value.new_local, false);
5100 try f.object.dg.renderTypeAndName(writer, input_ty, local_value, Const, .none, .complete);
5110 const input_local = try f.allocLocalValue(.{
5111 .ctype = try f.ctypeFromType(input_ty, .complete),
5112 .alignas = CType.AlignAs.fromAbiAlignment(input_ty.abiAlignment(zcu)),
5113 });
5114 try f.allocs.put(gpa, input_local.new_local, false);
5115 try f.object.dg.renderTypeAndName(writer, input_ty, input_local, Const, .none, .complete);
51015116 if (is_reg) {
51025117 try writer.writeAll(" __asm(\"");
51035118 try writer.writeAll(constraint["{".len .. constraint.len - "}".len]);
......@@ -5190,7 +5205,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
51905205 try f.writeCValue(writer, .{ .local = locals_index }, .Other);
51915206 locals_index += 1;
51925207 } else if (output == .none) {
5193 try f.writeCValue(writer, local, .FunctionArgument);
5208 try f.writeCValue(writer, inst_local, .FunctionArgument);
51945209 } else {
51955210 try f.writeCValueDeref(writer, try f.resolveInst(output));
51965211 }
......@@ -5246,7 +5261,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
52465261 const is_reg = constraint[1] == '{';
52475262 if (is_reg) {
52485263 try f.writeCValueDeref(writer, if (output == .none)
5249 .{ .local_ref = local.new_local }
5264 .{ .local_ref = inst_local.new_local }
52505265 else
52515266 try f.resolveInst(output));
52525267 try writer.writeAll(" = ");
......@@ -5256,7 +5271,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue {
52565271 }
52575272 }
52585273
5259 break :result if (f.liveness.isUnused(inst)) .none else local;
5274 break :result if (f.liveness.isUnused(inst)) .none else inst_local;
52605275 };
52615276
52625277 var bt = iterateBigTomb(f, inst);
......@@ -6690,25 +6705,15 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue {
66906705 try writeSliceOrPtr(f, writer, src_ptr, src_ty);
66916706 try writer.writeAll(", ");
66926707 switch (dest_ty.ptrSize(zcu)) {
6693 .Slice => {
6694 const elem_ty = dest_ty.childType(zcu);
6695 const elem_abi_size = elem_ty.abiSize(zcu);
6696 try f.writeCValueMember(writer, dest_ptr, .{ .identifier = "len" });
6697 if (elem_abi_size > 1) {
6698 try writer.print(" * {d});\n", .{elem_abi_size});
6699 } else {
6700 try writer.writeAll(");\n");
6701 }
6702 },
6703 .One => {
6704 const array_ty = dest_ty.childType(zcu);
6705 const elem_ty = array_ty.childType(zcu);
6706 const elem_abi_size = elem_ty.abiSize(zcu);
6707 const len = array_ty.arrayLen(zcu) * elem_abi_size;
6708 try writer.print("{d});\n", .{len});
6709 },
6708 .One => try writer.print("{}", .{
6709 try f.fmtIntLiteral(try zcu.intValue(Type.usize, dest_ty.childType(zcu).arrayLen(zcu))),
6710 }),
67106711 .Many, .C => unreachable,
6712 .Slice => try f.writeCValueMember(writer, dest_ptr, .{ .identifier = "len" }),
67116713 }
6714 try writer.writeAll(" * sizeof(");
6715 try f.renderType(writer, dest_ty.elemType2(zcu));
6716 try writer.writeAll("));\n");
67126717
67136718 try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs });
67146719 return .none;
src/codegen/c/Type.zig+48-29
......@@ -734,6 +734,8 @@ pub const Info = union(enum) {
734734 aggregate: Aggregate,
735735 function: Function,
736736
737 const Tag = @typeInfo(Info).Union.tag_type.?;
738
737739 pub const Pointer = struct {
738740 elem_ctype: CType,
739741 @"const": bool = false,
......@@ -761,7 +763,7 @@ pub const Info = union(enum) {
761763 len: u64,
762764 };
763765
764 pub const Tag = enum { @"enum", @"struct", @"union" };
766 pub const AggregateTag = enum { @"enum", @"struct", @"union" };
765767
766768 pub const Field = struct {
767769 name: String,
......@@ -820,7 +822,7 @@ pub const Info = union(enum) {
820822 };
821823
822824 pub const FwdDecl = struct {
823 tag: Tag,
825 tag: AggregateTag,
824826 name: union(enum) {
825827 anon: Field.Slice,
826828 owner_decl: DeclIndex,
......@@ -828,7 +830,7 @@ pub const Info = union(enum) {
828830 };
829831
830832 pub const Aggregate = struct {
831 tag: Tag,
833 tag: AggregateTag,
832834 @"packed": bool = false,
833835 name: union(enum) {
834836 anon: struct {
......@@ -853,9 +855,8 @@ pub const Info = union(enum) {
853855 rhs_pool: *const Pool,
854856 pool_adapter: anytype,
855857 ) bool {
856 const InfoTag = @typeInfo(Info).Union.tag_type.?;
857858 const rhs_info = rhs_ctype.info(rhs_pool);
858 if (@as(InfoTag, lhs_info) != @as(InfoTag, rhs_info)) return false;
859 if (@as(Info.Tag, lhs_info) != @as(Info.Tag, rhs_info)) return false;
859860 return switch (lhs_info) {
860861 .basic => |lhs_basic_info| lhs_basic_info == rhs_info.basic,
861862 .pointer => |lhs_pointer_info| lhs_pointer_info.@"const" == rhs_info.pointer.@"const" and
......@@ -1012,7 +1013,7 @@ pub const Pool = struct {
10121013 pool: *Pool,
10131014 allocator: std.mem.Allocator,
10141015 fwd_decl_info: struct {
1015 tag: Info.Tag,
1016 tag: Info.AggregateTag,
10161017 name: union(enum) {
10171018 anon: []const Info.Field,
10181019 owner_decl: DeclIndex,
......@@ -1070,7 +1071,7 @@ pub const Pool = struct {
10701071 pool: *Pool,
10711072 allocator: std.mem.Allocator,
10721073 aggregate_info: struct {
1073 tag: Info.Tag,
1074 tag: Info.AggregateTag,
10741075 @"packed": bool = false,
10751076 name: union(enum) {
10761077 anon: struct {
......@@ -1175,7 +1176,7 @@ pub const Pool = struct {
11751176 pub fn fromFields(
11761177 pool: *Pool,
11771178 allocator: std.mem.Allocator,
1178 tag: Info.Tag,
1179 tag: Info.AggregateTag,
11791180 fields: []Info.Field,
11801181 kind: Kind,
11811182 ) !CType {
......@@ -1390,8 +1391,8 @@ pub const Pool = struct {
13901391 else => |ip_index| switch (ip.indexToKey(ip_index)) {
13911392 .int_type => |int_info| return pool.fromIntInfo(allocator, int_info, mod, kind),
13921393 .ptr_type => |ptr_info| switch (ptr_info.flags.size) {
1393 .One, .Many, .C => return pool.getPointer(allocator, .{
1394 .elem_ctype = elem_ctype: {
1394 .One, .Many, .C => {
1395 const elem_ctype = elem_ctype: {
13951396 if (ptr_info.packed_offset.host_size > 0 and
13961397 ptr_info.flags.vector_index == .none)
13971398 break :elem_ctype try pool.fromIntInfo(allocator, .{
......@@ -1412,13 +1413,31 @@ pub const Pool = struct {
14121413 .abi = Type.fromInterned(ptr_info.child).abiAlignment(zcu),
14131414 }),
14141415 };
1415 if (elem.alignas.abiOrder().compare(.gte))
1416 break :elem_ctype elem.ctype;
1417 break :elem_ctype try pool.getAligned(allocator, elem);
1418 },
1419 .@"const" = ptr_info.flags.is_const,
1420 .@"volatile" = ptr_info.flags.is_volatile,
1421 }),
1416 break :elem_ctype if (elem.alignas.abiOrder().compare(.gte))
1417 elem.ctype
1418 else
1419 try pool.getAligned(allocator, elem);
1420 };
1421 const elem_tag: Info.Tag = switch (elem_ctype.info(pool)) {
1422 .aligned => |aligned_info| aligned_info.ctype.info(pool),
1423 else => |elem_tag| elem_tag,
1424 };
1425 return pool.getPointer(allocator, .{
1426 .elem_ctype = elem_ctype,
1427 .@"const" = switch (elem_tag) {
1428 .basic,
1429 .pointer,
1430 .aligned,
1431 .array,
1432 .vector,
1433 .fwd_decl,
1434 .aggregate,
1435 => ptr_info.flags.is_const,
1436 .function => false,
1437 },
1438 .@"volatile" = ptr_info.flags.is_volatile,
1439 });
1440 },
14221441 .Slice => {
14231442 const target = &mod.resolved_target.result;
14241443 var fields = [_]Info.Field{
......@@ -1589,7 +1608,7 @@ pub const Pool = struct {
15891608 loaded_struct.field_types.len * @typeInfo(Field).Struct.fields.len,
15901609 );
15911610 var hasher = Hasher.init;
1592 var tag: Tag = .aggregate_struct;
1611 var tag: Pool.Tag = .aggregate_struct;
15931612 var field_it = loaded_struct.iterateRuntimeOrder(ip);
15941613 while (field_it.next()) |field_index| {
15951614 const field_type = Type.fromInterned(
......@@ -1729,7 +1748,7 @@ pub const Pool = struct {
17291748 loaded_union.field_types.len * @typeInfo(Field).Struct.fields.len,
17301749 );
17311750 var hasher = Hasher.init;
1732 var tag: Tag = .aggregate_union;
1751 var tag: Pool.Tag = .aggregate_union;
17331752 var payload_align: Alignment = .@"1";
17341753 for (0..loaded_union.field_types.len) |field_index| {
17351754 const field_type = Type.fromInterned(
......@@ -2093,7 +2112,7 @@ pub const Pool = struct {
20932112 inline for (@typeInfo(Extra).Struct.fields) |field| {
20942113 const value = @field(extra, field.name);
20952114 hasher.update(switch (field.type) {
2096 Tag, String, CType => unreachable,
2115 Pool.Tag, String, CType => unreachable,
20972116 CType.Index => (CType{ .index = value }).hash(pool),
20982117 String.Index => (String{ .index = value }).slice(pool),
20992118 else => value,
......@@ -2102,7 +2121,7 @@ pub const Pool = struct {
21022121 }
21032122 fn update(hasher: *Hasher, data: anytype) void {
21042123 switch (@TypeOf(data)) {
2105 Tag => @compileError("pass tag to final"),
2124 Pool.Tag => @compileError("pass tag to final"),
21062125 CType, CType.Index => @compileError("hash ctype.hash(pool) instead"),
21072126 String, String.Index => @compileError("hash string.slice(pool) instead"),
21082127 u32, DeclIndex, Aligned.Flags => hasher.impl.update(std.mem.asBytes(&data)),
......@@ -2111,7 +2130,7 @@ pub const Pool = struct {
21112130 }
21122131 }
21132132
2114 fn final(hasher: Hasher, tag: Tag) Map.Hash {
2133 fn final(hasher: Hasher, tag: Pool.Tag) Map.Hash {
21152134 var impl = hasher.impl;
21162135 impl.update(std.mem.asBytes(&tag));
21172136 return @truncate(impl.final());
......@@ -2122,11 +2141,11 @@ pub const Pool = struct {
21222141 pool: *Pool,
21232142 allocator: std.mem.Allocator,
21242143 hasher: Hasher,
2125 tag: Tag,
2144 tag: Pool.Tag,
21262145 data: u32,
21272146 ) !CType {
21282147 try pool.ensureUnusedCapacity(allocator, 1);
2129 const Key = struct { hash: Map.Hash, tag: Tag, data: u32 };
2148 const Key = struct { hash: Map.Hash, tag: Pool.Tag, data: u32 };
21302149 const CTypeAdapter = struct {
21312150 pool: *const Pool,
21322151 pub fn hash(_: @This(), key: Key) Map.Hash {
......@@ -2148,7 +2167,7 @@ pub const Pool = struct {
21482167 fn tagExtra(
21492168 pool: *Pool,
21502169 allocator: std.mem.Allocator,
2151 tag: Tag,
2170 tag: Pool.Tag,
21522171 comptime Extra: type,
21532172 extra: Extra,
21542173 ) !CType {
......@@ -2166,7 +2185,7 @@ pub const Pool = struct {
21662185 pool: *Pool,
21672186 allocator: std.mem.Allocator,
21682187 hasher: Hasher,
2169 tag: Tag,
2188 tag: Pool.Tag,
21702189 extra_index: ExtraIndex,
21712190 ) !CType {
21722191 try pool.ensureUnusedCapacity(allocator, 1);
......@@ -2176,10 +2195,10 @@ pub const Pool = struct {
21762195 fn tagTrailingExtraAssumeCapacity(
21772196 pool: *Pool,
21782197 hasher: Hasher,
2179 tag: Tag,
2198 tag: Pool.Tag,
21802199 extra_index: ExtraIndex,
21812200 ) CType {
2182 const Key = struct { hash: Map.Hash, tag: Tag, extra: []const u32 };
2201 const Key = struct { hash: Map.Hash, tag: Pool.Tag, extra: []const u32 };
21832202 const CTypeAdapter = struct {
21842203 pool: *const Pool,
21852204 pub fn hash(_: @This(), key: Key) Map.Hash {
......@@ -2239,7 +2258,7 @@ pub const Pool = struct {
22392258 }
22402259
22412260 const Item = struct {
2242 tag: Tag,
2261 tag: Pool.Tag,
22432262 data: u32,
22442263 };
22452264