| author | |
| committer | |
| log | 12f3c461a4429d9c7a0ddbaa6465bf0499a99b8c |
| tree | fbe7dffade76aed2f015c1a9029abe76bf25e590 |
| parent | c9b6f1bf907a0083f1fb0eba2f6969fd8f7f3b64 |
9 files changed, 82 insertions(+), 44 deletions(-)
lib/std/builtin.zig+1-3| ... | ... | @@ -753,9 +753,7 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace) noreturn |
| 753 | 753 | @setCold(true); |
| 754 | 754 | // Until self-hosted catches up with stage1 language features, we have a simpler |
| 755 | 755 | // default panic function: |
| 756 | const panic_works = builtin.zig_backend == .stage1 or | |
| 757 | (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .linux); | |
| 758 | if (!panic_works) { | |
| 756 | if (builtin.zig_backend != .stage1 and builtin.zig_backend != .stage2_llvm) { | |
| 759 | 757 | while (true) { |
| 760 | 758 | @breakpoint(); |
| 761 | 759 | } |
lib/std/c/darwin.zig+10-6| ... | ... | @@ -624,8 +624,7 @@ pub const pthread_attr_t = extern struct { |
| 624 | 624 | __opaque: [56]u8, |
| 625 | 625 | }; |
| 626 | 626 | |
| 627 | const pthread_t = std.c.pthread_t; | |
| 628 | pub extern "c" fn pthread_threadid_np(thread: ?pthread_t, thread_id: *u64) c_int; | |
| 627 | pub extern "c" fn pthread_threadid_np(thread: ?std.c.pthread_t, thread_id: *u64) c_int; | |
| 629 | 628 | pub extern "c" fn pthread_setname_np(name: [*:0]const u8) E; |
| 630 | 629 | pub extern "c" fn pthread_getname_np(thread: std.c.pthread_t, name: [*:0]u8, len: usize) E; |
| 631 | 630 | |
| ... | ... | @@ -921,12 +920,17 @@ pub const siginfo_t = extern struct { |
| 921 | 920 | |
| 922 | 921 | /// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name. |
| 923 | 922 | pub const Sigaction = extern struct { |
| 924 | pub const handler_fn = fn (c_int) callconv(.C) void; | |
| 925 | pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const anyopaque) callconv(.C) void; | |
| 923 | pub usingnamespace if (builtin.zig_backend == .stage1) struct { | |
| 924 | pub const handler_fn = fn (c_int) callconv(.C) void; | |
| 925 | pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const anyopaque) callconv(.C) void; | |
| 926 | } else struct { | |
| 927 | pub const handler_fn = *const fn (c_int) callconv(.C) void; | |
| 928 | pub const sigaction_fn = *const fn (c_int, *const siginfo_t, ?*const anyopaque) callconv(.C) void; | |
| 929 | }; | |
| 926 | 930 | |
| 927 | 931 | handler: extern union { |
| 928 | handler: ?handler_fn, | |
| 929 | sigaction: ?sigaction_fn, | |
| 932 | handler: ?Sigaction.handler_fn, | |
| 933 | sigaction: ?Sigaction.sigaction_fn, | |
| 930 | 934 | }, |
| 931 | 935 | mask: sigset_t, |
| 932 | 936 | flags: c_uint, |
lib/std/heap/general_purpose_allocator.zig+6-18| ... | ... | @@ -341,15 +341,9 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 341 | 341 | const slot_index = @intCast(SlotIndex, used_bits_byte * 8 + bit_index); |
| 342 | 342 | const stack_trace = bucketStackTrace(bucket, size_class, slot_index, .alloc); |
| 343 | 343 | const addr = bucket.page + slot_index * size_class; |
| 344 | if (builtin.zig_backend == .stage1 or builtin.os.tag == .linux) { | |
| 345 | log.err("memory address 0x{x} leaked: {s}", .{ | |
| 346 | @ptrToInt(addr), stack_trace, | |
| 347 | }); | |
| 348 | } else { // TODO | |
| 349 | log.err("memory address 0x{x} leaked", .{ | |
| 350 | @ptrToInt(addr), | |
| 351 | }); | |
| 352 | } | |
| 344 | log.err("memory address 0x{x} leaked: {s}", .{ | |
| 345 | @ptrToInt(addr), stack_trace, | |
| 346 | }); | |
| 353 | 347 | leaks = true; |
| 354 | 348 | } |
| 355 | 349 | if (bit_index == math.maxInt(u3)) |
| ... | ... | @@ -379,15 +373,9 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 379 | 373 | while (it.next()) |large_alloc| { |
| 380 | 374 | if (config.retain_metadata and large_alloc.freed) continue; |
| 381 | 375 | const stack_trace = large_alloc.getStackTrace(.alloc); |
| 382 | if (builtin.zig_backend == .stage1 or builtin.os.tag == .linux) { | |
| 383 | log.err("memory address 0x{x} leaked: {s}", .{ | |
| 384 | @ptrToInt(large_alloc.bytes.ptr), stack_trace, | |
| 385 | }); | |
| 386 | } else { // TODO | |
| 387 | log.err("memory address 0x{x} leaked", .{ | |
| 388 | @ptrToInt(large_alloc.bytes.ptr), | |
| 389 | }); | |
| 390 | } | |
| 376 | log.err("memory address 0x{x} leaked: {s}", .{ | |
| 377 | @ptrToInt(large_alloc.bytes.ptr), stack_trace, | |
| 378 | }); | |
| 391 | 379 | leaks = true; |
| 392 | 380 | } |
| 393 | 381 | return leaks; |
lib/std/macho.zig+3-1| ... | ... | @@ -624,7 +624,9 @@ pub const segment_command_64 = extern struct { |
| 624 | 624 | cmd: LC = .SEGMENT_64, |
| 625 | 625 | |
| 626 | 626 | /// includes sizeof section_64 structs |
| 627 | cmdsize: u32 = @sizeOf(segment_command_64), | |
| 627 | cmdsize: u32, | |
| 628 | // TODO lazy values in stage2 | |
| 629 | // cmdsize: u32 = @sizeOf(segment_command_64), | |
| 628 | 630 | |
| 629 | 631 | /// segment name |
| 630 | 632 | segname: [16]u8, |
src/Sema.zig+25-9| ... | ... | @@ -131,6 +131,9 @@ pub const Block = struct { |
| 131 | 131 | |
| 132 | 132 | c_import_buf: ?*std.ArrayList(u8) = null, |
| 133 | 133 | |
| 134 | /// type of `err` in `else => |err|` | |
| 135 | switch_else_err_ty: ?Type = null, | |
| 136 | ||
| 134 | 137 | const Param = struct { |
| 135 | 138 | /// `noreturn` means `anytype`. |
| 136 | 139 | ty: Type, |
| ... | ... | @@ -189,6 +192,7 @@ pub const Block = struct { |
| 189 | 192 | .runtime_index = parent.runtime_index, |
| 190 | 193 | .want_safety = parent.want_safety, |
| 191 | 194 | .c_import_buf = parent.c_import_buf, |
| 195 | .switch_else_err_ty = parent.switch_else_err_ty, | |
| 192 | 196 | }; |
| 193 | 197 | } |
| 194 | 198 | |
| ... | ... | @@ -6714,12 +6718,6 @@ fn zirSwitchCapture( |
| 6714 | 6718 | |
| 6715 | 6719 | if (capture_info.prong_index == std.math.maxInt(@TypeOf(capture_info.prong_index))) { |
| 6716 | 6720 | // It is the else/`_` prong. |
| 6717 | switch (operand_ty.zigTypeTag()) { | |
| 6718 | .ErrorSet => { | |
| 6719 | return sema.fail(block, operand_src, "TODO implement Sema for zirSwitchCaptureElse for error sets", .{}); | |
| 6720 | }, | |
| 6721 | else => {}, | |
| 6722 | } | |
| 6723 | 6721 | if (is_ref) { |
| 6724 | 6722 | assert(operand_is_ref); |
| 6725 | 6723 | return operand_ptr; |
| ... | ... | @@ -6730,7 +6728,10 @@ fn zirSwitchCapture( |
| 6730 | 6728 | else |
| 6731 | 6729 | operand_ptr; |
| 6732 | 6730 | |
| 6733 | return operand; | |
| 6731 | switch (operand_ty.zigTypeTag()) { | |
| 6732 | .ErrorSet => return sema.bitCast(block, block.switch_else_err_ty.?, operand, operand_src), | |
| 6733 | else => return operand, | |
| 6734 | } | |
| 6734 | 6735 | } |
| 6735 | 6736 | |
| 6736 | 6737 | if (is_multi) { |
| ... | ... | @@ -6907,6 +6908,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 6907 | 6908 | |
| 6908 | 6909 | const operand_ty = sema.typeOf(operand); |
| 6909 | 6910 | |
| 6911 | var else_error_ty: ?Type = null; | |
| 6912 | ||
| 6910 | 6913 | // Validate usage of '_' prongs. |
| 6911 | 6914 | if (special_prong == .under and !operand_ty.isNonexhaustiveEnum()) { |
| 6912 | 6915 | const msg = msg: { |
| ... | ... | @@ -7099,6 +7102,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 7099 | 7102 | .{}, |
| 7100 | 7103 | ); |
| 7101 | 7104 | } |
| 7105 | else_error_ty = Type.@"anyerror"; | |
| 7102 | 7106 | } else { |
| 7103 | 7107 | var maybe_msg: ?*Module.ErrorMsg = null; |
| 7104 | 7108 | errdefer if (maybe_msg) |msg| msg.destroy(sema.gpa); |
| ... | ... | @@ -7143,6 +7147,17 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 7143 | 7147 | .{}, |
| 7144 | 7148 | ); |
| 7145 | 7149 | } |
| 7150 | ||
| 7151 | const error_names = operand_ty.errorSetNames(); | |
| 7152 | var names: Module.ErrorSet.NameMap = .{}; | |
| 7153 | try names.ensureUnusedCapacity(sema.arena, error_names.len); | |
| 7154 | for (error_names) |error_name| { | |
| 7155 | if (seen_errors.contains(error_name)) continue; | |
| 7156 | ||
| 7157 | names.putAssumeCapacityNoClobber(error_name, {}); | |
| 7158 | } | |
| 7159 | ||
| 7160 | else_error_ty = try Type.Tag.error_set_merged.create(sema.arena, names); | |
| 7146 | 7161 | } |
| 7147 | 7162 | }, |
| 7148 | 7163 | .Union => return sema.fail(block, src, "TODO validate switch .Union", .{}), |
| ... | ... | @@ -7420,6 +7435,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 7420 | 7435 | .label = &label, |
| 7421 | 7436 | .inlining = block.inlining, |
| 7422 | 7437 | .is_comptime = block.is_comptime, |
| 7438 | .switch_else_err_ty = else_error_ty, | |
| 7423 | 7439 | }; |
| 7424 | 7440 | const merges = &child_block.label.?.merges; |
| 7425 | 7441 | defer child_block.instructions.deinit(gpa); |
| ... | ... | @@ -18523,8 +18539,8 @@ pub fn bitCastVal( |
| 18523 | 18539 | const abi_size = try sema.usizeCast(block, src, old_ty.abiSize(target)); |
| 18524 | 18540 | const buffer = try sema.gpa.alloc(u8, abi_size); |
| 18525 | 18541 | defer sema.gpa.free(buffer); |
| 18526 | val.writeToMemory(old_ty, target, buffer); | |
| 18527 | return Value.readFromMemory(new_ty, target, buffer[buffer_offset..], sema.arena); | |
| 18542 | val.writeToMemory(old_ty, sema.mod, buffer); | |
| 18543 | return Value.readFromMemory(new_ty, sema.mod, buffer[buffer_offset..], sema.arena); | |
| 18528 | 18544 | } |
| 18529 | 18545 | |
| 18530 | 18546 | fn coerceArrayPtrToSlice( |
src/link/MachO.zig+5| ... | ... | @@ -4301,6 +4301,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 4301 | 4301 | .inner = .{ |
| 4302 | 4302 | .segname = makeStaticString("__PAGEZERO"), |
| 4303 | 4303 | .vmsize = pagezero_vmsize, |
| 4304 | .cmdsize = @sizeOf(macho.segment_command_64), | |
| 4304 | 4305 | }, |
| 4305 | 4306 | }, |
| 4306 | 4307 | }); |
| ... | ... | @@ -4326,6 +4327,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 4326 | 4327 | .filesize = needed_size, |
| 4327 | 4328 | .maxprot = macho.PROT.READ | macho.PROT.EXEC, |
| 4328 | 4329 | .initprot = macho.PROT.READ | macho.PROT.EXEC, |
| 4330 | .cmdsize = @sizeOf(macho.segment_command_64), | |
| 4329 | 4331 | }, |
| 4330 | 4332 | }, |
| 4331 | 4333 | }); |
| ... | ... | @@ -4431,6 +4433,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 4431 | 4433 | .filesize = needed_size, |
| 4432 | 4434 | .maxprot = macho.PROT.READ | macho.PROT.WRITE, |
| 4433 | 4435 | .initprot = macho.PROT.READ | macho.PROT.WRITE, |
| 4436 | .cmdsize = @sizeOf(macho.segment_command_64), | |
| 4434 | 4437 | }, |
| 4435 | 4438 | }, |
| 4436 | 4439 | }); |
| ... | ... | @@ -4480,6 +4483,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 4480 | 4483 | .filesize = needed_size, |
| 4481 | 4484 | .maxprot = macho.PROT.READ | macho.PROT.WRITE, |
| 4482 | 4485 | .initprot = macho.PROT.READ | macho.PROT.WRITE, |
| 4486 | .cmdsize = @sizeOf(macho.segment_command_64), | |
| 4483 | 4487 | }, |
| 4484 | 4488 | }, |
| 4485 | 4489 | }); |
| ... | ... | @@ -4589,6 +4593,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 4589 | 4593 | .fileoff = fileoff, |
| 4590 | 4594 | .maxprot = macho.PROT.READ, |
| 4591 | 4595 | .initprot = macho.PROT.READ, |
| 4596 | .cmdsize = @sizeOf(macho.segment_command_64), | |
| 4592 | 4597 | }, |
| 4593 | 4598 | }, |
| 4594 | 4599 | }); |
src/link/MachO/DebugSymbols.zig+1| ... | ... | @@ -148,6 +148,7 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: Allocator) !void |
| 148 | 148 | .vmsize = needed_size, |
| 149 | 149 | .fileoff = fileoff, |
| 150 | 150 | .filesize = needed_size, |
| 151 | .cmdsize = @sizeOf(macho.segment_command_64), | |
| 151 | 152 | }, |
| 152 | 153 | }, |
| 153 | 154 | }); |
src/value.zig+26-6| ... | ... | @@ -1042,7 +1042,8 @@ pub const Value = extern union { |
| 1042 | 1042 | }; |
| 1043 | 1043 | } |
| 1044 | 1044 | |
| 1045 | pub fn writeToMemory(val: Value, ty: Type, target: Target, buffer: []u8) void { | |
| 1045 | pub fn writeToMemory(val: Value, ty: Type, mod: *Module, buffer: []u8) void { | |
| 1046 | const target = mod.getTarget(); | |
| 1046 | 1047 | if (val.isUndef()) { |
| 1047 | 1048 | const size = @intCast(usize, ty.abiSize(target)); |
| 1048 | 1049 | std.mem.set(u8, buffer[0..size], 0xaa); |
| ... | ... | @@ -1081,7 +1082,7 @@ pub const Value = extern union { |
| 1081 | 1082 | var buf_off: usize = 0; |
| 1082 | 1083 | while (elem_i < len) : (elem_i += 1) { |
| 1083 | 1084 | const elem_val = val.elemValueBuffer(elem_i, &elem_value_buf); |
| 1084 | writeToMemory(elem_val, elem_ty, target, buffer[buf_off..]); | |
| 1085 | writeToMemory(elem_val, elem_ty, mod, buffer[buf_off..]); | |
| 1085 | 1086 | buf_off += elem_size; |
| 1086 | 1087 | } |
| 1087 | 1088 | }, |
| ... | ... | @@ -1092,7 +1093,7 @@ pub const Value = extern union { |
| 1092 | 1093 | const field_vals = val.castTag(.aggregate).?.data; |
| 1093 | 1094 | for (fields) |field, i| { |
| 1094 | 1095 | const off = @intCast(usize, ty.structFieldOffset(i, target)); |
| 1095 | writeToMemory(field_vals[i], field.ty, target, buffer[off..]); | |
| 1096 | writeToMemory(field_vals[i], field.ty, mod, buffer[off..]); | |
| 1096 | 1097 | } |
| 1097 | 1098 | }, |
| 1098 | 1099 | .Packed => { |
| ... | ... | @@ -1105,6 +1106,12 @@ pub const Value = extern union { |
| 1105 | 1106 | host_int.writeTwosComplement(buffer, bit_size, abi_size, target.cpu.arch.endian()); |
| 1106 | 1107 | }, |
| 1107 | 1108 | }, |
| 1109 | .ErrorSet => { | |
| 1110 | // TODO revisit this when we have the concept of the error tag type | |
| 1111 | const Int = u16; | |
| 1112 | const int = mod.global_error_set.get(val.castTag(.@"error").?.data.name).?; | |
| 1113 | std.mem.writeInt(Int, buffer[0..@sizeOf(Int)], @intCast(Int, int), target.cpu.arch.endian()); | |
| 1114 | }, | |
| 1108 | 1115 | else => @panic("TODO implement writeToMemory for more types"), |
| 1109 | 1116 | } |
| 1110 | 1117 | } |
| ... | ... | @@ -1153,10 +1160,11 @@ pub const Value = extern union { |
| 1153 | 1160 | |
| 1154 | 1161 | pub fn readFromMemory( |
| 1155 | 1162 | ty: Type, |
| 1156 | target: Target, | |
| 1163 | mod: *Module, | |
| 1157 | 1164 | buffer: []const u8, |
| 1158 | 1165 | arena: Allocator, |
| 1159 | 1166 | ) Allocator.Error!Value { |
| 1167 | const target = mod.getTarget(); | |
| 1160 | 1168 | switch (ty.zigTypeTag()) { |
| 1161 | 1169 | .Int => { |
| 1162 | 1170 | if (buffer.len == 0) return Value.zero; |
| ... | ... | @@ -1184,7 +1192,7 @@ pub const Value = extern union { |
| 1184 | 1192 | const elems = try arena.alloc(Value, @intCast(usize, ty.arrayLen())); |
| 1185 | 1193 | var offset: usize = 0; |
| 1186 | 1194 | for (elems) |*elem| { |
| 1187 | elem.* = try readFromMemory(elem_ty, target, buffer[offset..], arena); | |
| 1195 | elem.* = try readFromMemory(elem_ty, mod, buffer[offset..], arena); | |
| 1188 | 1196 | offset += @intCast(usize, elem_size); |
| 1189 | 1197 | } |
| 1190 | 1198 | return Tag.aggregate.create(arena, elems); |
| ... | ... | @@ -1196,7 +1204,7 @@ pub const Value = extern union { |
| 1196 | 1204 | const field_vals = try arena.alloc(Value, fields.len); |
| 1197 | 1205 | for (fields) |field, i| { |
| 1198 | 1206 | const off = @intCast(usize, ty.structFieldOffset(i, target)); |
| 1199 | field_vals[i] = try readFromMemory(field.ty, target, buffer[off..], arena); | |
| 1207 | field_vals[i] = try readFromMemory(field.ty, mod, buffer[off..], arena); | |
| 1200 | 1208 | } |
| 1201 | 1209 | return Tag.aggregate.create(arena, field_vals); |
| 1202 | 1210 | }, |
| ... | ... | @@ -1212,6 +1220,18 @@ pub const Value = extern union { |
| 1212 | 1220 | return intToPackedStruct(ty, target, bigint.toConst(), arena); |
| 1213 | 1221 | }, |
| 1214 | 1222 | }, |
| 1223 | .ErrorSet => { | |
| 1224 | // TODO revisit this when we have the concept of the error tag type | |
| 1225 | const Int = u16; | |
| 1226 | const int = std.mem.readInt(Int, buffer[0..@sizeOf(Int)], target.cpu.arch.endian()); | |
| 1227 | ||
| 1228 | const payload = try arena.create(Value.Payload.Error); | |
| 1229 | payload.* = .{ | |
| 1230 | .base = .{ .tag = .@"error" }, | |
| 1231 | .data = .{ .name = mod.error_name_list.items[@intCast(usize, int)] }, | |
| 1232 | }; | |
| 1233 | return Value.initPayload(&payload.base); | |
| 1234 | }, | |
| 1215 | 1235 | else => @panic("TODO implement readFromMemory for more types"), |
| 1216 | 1236 | } |
| 1217 | 1237 | } |
test/behavior/switch.zig+5-1| ... | ... | @@ -430,7 +430,11 @@ test "switch on integer with else capturing expr" { |
| 430 | 430 | } |
| 431 | 431 | |
| 432 | 432 | test "else prong of switch on error set excludes other cases" { |
| 433 | if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO | |
| 433 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 434 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 435 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 436 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | |
| 437 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | |
| 434 | 438 | |
| 435 | 439 | const S = struct { |
| 436 | 440 | fn doTheTest() !void { |