| author | |
| committer | |
| log | 69e6d455ce8e21835ec3ce268a0533e0e7666e8b |
| tree | 8bdc050b60371970ddc8c1d1263a3688e79456aa |
| parent | c6cf40a0c03822cac3112be58c61ca55d436b5d0 |
| parent | 12f3c461a4429d9c7a0ddbaa6465bf0499a99b8c |
| signature |
enable default panic handler for stage2 LLVM12 files changed, 183 insertions(+), 77 deletions(-)
lib/std/builtin.zig+1-1| ... | ... | @@ -753,7 +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 | if (builtin.zig_backend != .stage1) { | |
| 756 | if (builtin.zig_backend != .stage1 and builtin.zig_backend != .stage2_llvm) { | |
| 757 | 757 | while (true) { |
| 758 | 758 | @breakpoint(); |
| 759 | 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/debug.zig-1| ... | ... | @@ -1541,7 +1541,6 @@ pub const ModuleDebugInfo = switch (native_os) { |
| 1541 | 1541 | .symbol_name = o_file_di.getSymbolName(relocated_address_o) orelse "???", |
| 1542 | 1542 | .compile_unit_name = compile_unit.die.getAttrString(o_file_di, DW.AT.name) catch |err| switch (err) { |
| 1543 | 1543 | error.MissingDebugInfo, error.InvalidDebugInfo => "???", |
| 1544 | else => return err, | |
| 1545 | 1544 | }, |
| 1546 | 1545 | .line_info = o_file_di.getLineNumberInfo(compile_unit.*, relocated_address_o + addr_off) catch |err| switch (err) { |
| 1547 | 1546 | error.MissingDebugInfo, error.InvalidDebugInfo => null, |
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) { | |
| 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) { | |
| 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, |
lib/std/os/linux.zig+36-13| ... | ... | @@ -1080,12 +1080,19 @@ pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigact |
| 1080 | 1080 | const mask_size = @sizeOf(@TypeOf(ksa.mask)); |
| 1081 | 1081 | |
| 1082 | 1082 | if (act) |new| { |
| 1083 | const restorer_fn = if ((new.flags & SA.SIGINFO) != 0) restore_rt else restore; | |
| 1083 | const restore_rt_ptr = if (builtin.zig_backend == .stage1) restore_rt else &syscall_bits.restore_rt; | |
| 1084 | // TODO https://github.com/ziglang/zig/issues/11227 | |
| 1085 | const restore_ptr = if (builtin.zig_backend == .stage1) restore else switch (native_arch) { | |
| 1086 | .arm, .thumb, .mips, .mipsel, .i386 => &syscall_bits.restore, | |
| 1087 | .x86_64, .aarch64, .riscv64, .sparcv9, .powerpc, .powerpc64, .powerpc64le => &syscall_bits.restore_rt, | |
| 1088 | else => unreachable, | |
| 1089 | }; | |
| 1090 | const restorer_fn = if ((new.flags & SA.SIGINFO) != 0) restore_rt_ptr else restore_ptr; | |
| 1084 | 1091 | ksa = k_sigaction{ |
| 1085 | 1092 | .handler = new.handler.handler, |
| 1086 | 1093 | .flags = new.flags | SA.RESTORER, |
| 1087 | 1094 | .mask = undefined, |
| 1088 | .restorer = @ptrCast(fn () callconv(.C) void, restorer_fn), | |
| 1095 | .restorer = @ptrCast(k_sigaction_funcs.restorer, restorer_fn), | |
| 1089 | 1096 | }; |
| 1090 | 1097 | @memcpy(@ptrCast([*]u8, &ksa.mask), @ptrCast([*]const u8, &new.mask), mask_size); |
| 1091 | 1098 | } |
| ... | ... | @@ -3047,39 +3054,55 @@ pub const sigset_t = [1024 / 32]u32; |
| 3047 | 3054 | pub const all_mask: sigset_t = [_]u32{0xffffffff} ** sigset_t.len; |
| 3048 | 3055 | pub const app_mask: sigset_t = [2]u32{ 0xfffffffc, 0x7fffffff } ++ [_]u32{0xffffffff} ** 30; |
| 3049 | 3056 | |
| 3057 | const k_sigaction_funcs = if (builtin.zig_backend == .stage1) struct { | |
| 3058 | const handler = ?fn (c_int) callconv(.C) void; | |
| 3059 | const restorer = fn () callconv(.C) void; | |
| 3060 | } else struct { | |
| 3061 | const handler = ?*const fn (c_int) callconv(.C) void; | |
| 3062 | const restorer = *const fn () callconv(.C) void; | |
| 3063 | }; | |
| 3064 | ||
| 3050 | 3065 | pub const k_sigaction = switch (native_arch) { |
| 3051 | 3066 | .mips, .mipsel => extern struct { |
| 3052 | 3067 | flags: c_uint, |
| 3053 | handler: ?fn (c_int) callconv(.C) void, | |
| 3068 | handler: k_sigaction_funcs.handler, | |
| 3054 | 3069 | mask: [4]c_ulong, |
| 3055 | restorer: fn () callconv(.C) void, | |
| 3070 | restorer: k_sigaction_funcs.restorer, | |
| 3056 | 3071 | }, |
| 3057 | 3072 | .mips64, .mips64el => extern struct { |
| 3058 | 3073 | flags: c_uint, |
| 3059 | handler: ?fn (c_int) callconv(.C) void, | |
| 3074 | handler: k_sigaction_funcs.handler, | |
| 3060 | 3075 | mask: [2]c_ulong, |
| 3061 | restorer: fn () callconv(.C) void, | |
| 3076 | restorer: k_sigaction_funcs.restorer, | |
| 3062 | 3077 | }, |
| 3063 | 3078 | else => extern struct { |
| 3064 | handler: ?fn (c_int) callconv(.C) void, | |
| 3079 | handler: k_sigaction_funcs.handler, | |
| 3065 | 3080 | flags: c_ulong, |
| 3066 | restorer: fn () callconv(.C) void, | |
| 3081 | restorer: k_sigaction_funcs.restorer, | |
| 3067 | 3082 | mask: [2]c_uint, |
| 3068 | 3083 | }, |
| 3069 | 3084 | }; |
| 3070 | 3085 | |
| 3071 | 3086 | /// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall. |
| 3072 | 3087 | pub const Sigaction = extern struct { |
| 3073 | pub const handler_fn = fn (c_int) callconv(.C) void; | |
| 3074 | pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const anyopaque) callconv(.C) void; | |
| 3088 | pub usingnamespace if (builtin.zig_backend == .stage1) struct { | |
| 3089 | pub const handler_fn = fn (c_int) callconv(.C) void; | |
| 3090 | pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const anyopaque) callconv(.C) void; | |
| 3091 | } else struct { | |
| 3092 | pub const handler_fn = *const fn (c_int) callconv(.C) void; | |
| 3093 | pub const sigaction_fn = *const fn (c_int, *const siginfo_t, ?*const anyopaque) callconv(.C) void; | |
| 3094 | }; | |
| 3075 | 3095 | |
| 3076 | 3096 | handler: extern union { |
| 3077 | handler: ?handler_fn, | |
| 3078 | sigaction: ?sigaction_fn, | |
| 3097 | handler: ?Sigaction.handler_fn, | |
| 3098 | sigaction: ?Sigaction.sigaction_fn, | |
| 3079 | 3099 | }, |
| 3080 | 3100 | mask: sigset_t, |
| 3081 | 3101 | flags: c_uint, |
| 3082 | restorer: ?fn () callconv(.C) void = null, | |
| 3102 | restorer: ?if (builtin.zig_backend == .stage1) | |
| 3103 | fn () callconv(.C) void | |
| 3104 | else | |
| 3105 | *const fn () callconv(.C) void = null, | |
| 3083 | 3106 | }; |
| 3084 | 3107 | |
| 3085 | 3108 | pub const empty_sigset = [_]u32{0} ** @typeInfo(sigset_t).Array.len; |
src/Sema.zig+88-29| ... | ... | @@ -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 | |
| ... | ... | @@ -3930,6 +3934,23 @@ fn analyzeBlockBody( |
| 3930 | 3934 | // to emit a jump instruction to after the block when it encounters the break. |
| 3931 | 3935 | try parent_block.instructions.append(gpa, merges.block_inst); |
| 3932 | 3936 | const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items, .none); |
| 3937 | ||
| 3938 | const type_src = src; // TODO: better source location | |
| 3939 | const valid_rt = try sema.validateRunTimeType(child_block, type_src, resolved_ty, false); | |
| 3940 | if (!valid_rt) { | |
| 3941 | const msg = msg: { | |
| 3942 | const msg = try sema.errMsg(child_block, type_src, "value with comptime only type '{}' depends on runtime control flow", .{resolved_ty}); | |
| 3943 | errdefer msg.destroy(sema.gpa); | |
| 3944 | ||
| 3945 | const runtime_src = child_block.runtime_cond orelse child_block.runtime_loop.?; | |
| 3946 | try sema.errNote(child_block, runtime_src, msg, "runtime control flow here", .{}); | |
| 3947 | ||
| 3948 | try sema.explainWhyTypeIsComptime(child_block, type_src, msg, type_src.toSrcLoc(child_block.src_decl), resolved_ty); | |
| 3949 | ||
| 3950 | break :msg msg; | |
| 3951 | }; | |
| 3952 | return sema.failWithOwnedErrorMsg(child_block, msg); | |
| 3953 | } | |
| 3933 | 3954 | const ty_inst = try sema.addType(resolved_ty); |
| 3934 | 3955 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + |
| 3935 | 3956 | child_block.instructions.items.len); |
| ... | ... | @@ -4191,6 +4212,11 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError |
| 4191 | 4212 | const br_ref = try start_block.addBr(label.merges.block_inst, operand); |
| 4192 | 4213 | try label.merges.results.append(sema.gpa, operand); |
| 4193 | 4214 | try label.merges.br_list.append(sema.gpa, Air.refToIndex(br_ref).?); |
| 4215 | block.runtime_index += 1; | |
| 4216 | if (block.runtime_cond == null and block.runtime_loop == null) { | |
| 4217 | block.runtime_cond = start_block.runtime_cond orelse start_block.runtime_loop; | |
| 4218 | block.runtime_loop = start_block.runtime_loop; | |
| 4219 | } | |
| 4194 | 4220 | return inst; |
| 4195 | 4221 | } |
| 4196 | 4222 | } |
| ... | ... | @@ -6692,12 +6718,6 @@ fn zirSwitchCapture( |
| 6692 | 6718 | |
| 6693 | 6719 | if (capture_info.prong_index == std.math.maxInt(@TypeOf(capture_info.prong_index))) { |
| 6694 | 6720 | // It is the else/`_` prong. |
| 6695 | switch (operand_ty.zigTypeTag()) { | |
| 6696 | .ErrorSet => { | |
| 6697 | return sema.fail(block, operand_src, "TODO implement Sema for zirSwitchCaptureElse for error sets", .{}); | |
| 6698 | }, | |
| 6699 | else => {}, | |
| 6700 | } | |
| 6701 | 6721 | if (is_ref) { |
| 6702 | 6722 | assert(operand_is_ref); |
| 6703 | 6723 | return operand_ptr; |
| ... | ... | @@ -6708,7 +6728,10 @@ fn zirSwitchCapture( |
| 6708 | 6728 | else |
| 6709 | 6729 | operand_ptr; |
| 6710 | 6730 | |
| 6711 | 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 | } | |
| 6712 | 6735 | } |
| 6713 | 6736 | |
| 6714 | 6737 | if (is_multi) { |
| ... | ... | @@ -6885,6 +6908,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 6885 | 6908 | |
| 6886 | 6909 | const operand_ty = sema.typeOf(operand); |
| 6887 | 6910 | |
| 6911 | var else_error_ty: ?Type = null; | |
| 6912 | ||
| 6888 | 6913 | // Validate usage of '_' prongs. |
| 6889 | 6914 | if (special_prong == .under and !operand_ty.isNonexhaustiveEnum()) { |
| 6890 | 6915 | const msg = msg: { |
| ... | ... | @@ -7077,6 +7102,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 7077 | 7102 | .{}, |
| 7078 | 7103 | ); |
| 7079 | 7104 | } |
| 7105 | else_error_ty = Type.@"anyerror"; | |
| 7080 | 7106 | } else { |
| 7081 | 7107 | var maybe_msg: ?*Module.ErrorMsg = null; |
| 7082 | 7108 | errdefer if (maybe_msg) |msg| msg.destroy(sema.gpa); |
| ... | ... | @@ -7121,6 +7147,17 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 7121 | 7147 | .{}, |
| 7122 | 7148 | ); |
| 7123 | 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); | |
| 7124 | 7161 | } |
| 7125 | 7162 | }, |
| 7126 | 7163 | .Union => return sema.fail(block, src, "TODO validate switch .Union", .{}), |
| ... | ... | @@ -7398,6 +7435,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 7398 | 7435 | .label = &label, |
| 7399 | 7436 | .inlining = block.inlining, |
| 7400 | 7437 | .is_comptime = block.is_comptime, |
| 7438 | .switch_else_err_ty = else_error_ty, | |
| 7401 | 7439 | }; |
| 7402 | 7440 | const merges = &child_block.label.?.merges; |
| 7403 | 7441 | defer child_block.instructions.deinit(gpa); |
| ... | ... | @@ -15447,6 +15485,26 @@ fn validateVarType( |
| 15447 | 15485 | var_ty: Type, |
| 15448 | 15486 | is_extern: bool, |
| 15449 | 15487 | ) CompileError!void { |
| 15488 | if (try sema.validateRunTimeType(block, src, var_ty, is_extern)) return; | |
| 15489 | ||
| 15490 | const msg = msg: { | |
| 15491 | const msg = try sema.errMsg(block, src, "variable of type '{}' must be const or comptime", .{var_ty}); | |
| 15492 | errdefer msg.destroy(sema.gpa); | |
| 15493 | ||
| 15494 | try sema.explainWhyTypeIsComptime(block, src, msg, src.toSrcLoc(block.src_decl), var_ty); | |
| 15495 | ||
| 15496 | break :msg msg; | |
| 15497 | }; | |
| 15498 | return sema.failWithOwnedErrorMsg(block, msg); | |
| 15499 | } | |
| 15500 | ||
| 15501 | fn validateRunTimeType( | |
| 15502 | sema: *Sema, | |
| 15503 | block: *Block, | |
| 15504 | src: LazySrcLoc, | |
| 15505 | var_ty: Type, | |
| 15506 | is_extern: bool, | |
| 15507 | ) CompileError!bool { | |
| 15450 | 15508 | var ty = var_ty; |
| 15451 | 15509 | while (true) switch (ty.zigTypeTag()) { |
| 15452 | 15510 | .Bool, |
| ... | ... | @@ -15457,7 +15515,7 @@ fn validateVarType( |
| 15457 | 15515 | .Frame, |
| 15458 | 15516 | .AnyFrame, |
| 15459 | 15517 | .Void, |
| 15460 | => return, | |
| 15518 | => return true, | |
| 15461 | 15519 | |
| 15462 | 15520 | .BoundFn, |
| 15463 | 15521 | .ComptimeFloat, |
| ... | ... | @@ -15468,21 +15526,21 @@ fn validateVarType( |
| 15468 | 15526 | .Undefined, |
| 15469 | 15527 | .Null, |
| 15470 | 15528 | .Fn, |
| 15471 | => break, | |
| 15529 | => return false, | |
| 15472 | 15530 | |
| 15473 | 15531 | .Pointer => { |
| 15474 | 15532 | const elem_ty = ty.childType(); |
| 15475 | 15533 | switch (elem_ty.zigTypeTag()) { |
| 15476 | .Opaque, .Fn => return, | |
| 15534 | .Opaque, .Fn => return true, | |
| 15477 | 15535 | else => ty = elem_ty, |
| 15478 | 15536 | } |
| 15479 | 15537 | }, |
| 15480 | .Opaque => if (is_extern) return else break, | |
| 15538 | .Opaque => return is_extern, | |
| 15481 | 15539 | |
| 15482 | 15540 | .Optional => { |
| 15483 | 15541 | var buf: Type.Payload.ElemType = undefined; |
| 15484 | 15542 | const child_ty = ty.optionalChild(&buf); |
| 15485 | return validateVarType(sema, block, src, child_ty, is_extern); | |
| 15543 | return validateRunTimeType(sema, block, src, child_ty, is_extern); | |
| 15486 | 15544 | }, |
| 15487 | 15545 | .Array, .Vector => ty = ty.elemType(), |
| 15488 | 15546 | |
| ... | ... | @@ -15490,23 +15548,10 @@ fn validateVarType( |
| 15490 | 15548 | |
| 15491 | 15549 | .Struct, .Union => { |
| 15492 | 15550 | const resolved_ty = try sema.resolveTypeFields(block, src, ty); |
| 15493 | if (try sema.typeRequiresComptime(block, src, resolved_ty)) { | |
| 15494 | break; | |
| 15495 | } else { | |
| 15496 | return; | |
| 15497 | } | |
| 15551 | const needs_comptime = try sema.typeRequiresComptime(block, src, resolved_ty); | |
| 15552 | return !needs_comptime; | |
| 15498 | 15553 | }, |
| 15499 | } else unreachable; // TODO should not need else unreachable | |
| 15500 | ||
| 15501 | const msg = msg: { | |
| 15502 | const msg = try sema.errMsg(block, src, "variable of type '{}' must be const or comptime", .{var_ty}); | |
| 15503 | errdefer msg.destroy(sema.gpa); | |
| 15504 | ||
| 15505 | try sema.explainWhyTypeIsComptime(block, src, msg, src.toSrcLoc(block.src_decl), var_ty); | |
| 15506 | ||
| 15507 | break :msg msg; | |
| 15508 | 15554 | }; |
| 15509 | return sema.failWithOwnedErrorMsg(block, msg); | |
| 15510 | 15555 | } |
| 15511 | 15556 | |
| 15512 | 15557 | fn explainWhyTypeIsComptime( |
| ... | ... | @@ -18494,8 +18539,8 @@ pub fn bitCastVal( |
| 18494 | 18539 | const abi_size = try sema.usizeCast(block, src, old_ty.abiSize(target)); |
| 18495 | 18540 | const buffer = try sema.gpa.alloc(u8, abi_size); |
| 18496 | 18541 | defer sema.gpa.free(buffer); |
| 18497 | val.writeToMemory(old_ty, target, buffer); | |
| 18498 | 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); | |
| 18499 | 18544 | } |
| 18500 | 18545 | |
| 18501 | 18546 | fn coerceArrayPtrToSlice( |
| ... | ... | @@ -20351,6 +20396,20 @@ pub fn resolveTypeFully( |
| 20351 | 20396 | return resolveTypeFully(sema, block, src, ty.optionalChild(&buf)); |
| 20352 | 20397 | }, |
| 20353 | 20398 | .ErrorUnion => return resolveTypeFully(sema, block, src, ty.errorUnionPayload()), |
| 20399 | .Fn => { | |
| 20400 | const info = ty.fnInfo(); | |
| 20401 | if (info.is_generic) { | |
| 20402 | // Resolving of generic function types is defeerred to when | |
| 20403 | // the function is instantiated. | |
| 20404 | return; | |
| 20405 | } | |
| 20406 | for (info.param_types) |param_ty| { | |
| 20407 | const param_ty_src = src; // TODO better source location | |
| 20408 | try sema.resolveTypeFully(block, param_ty_src, param_ty); | |
| 20409 | } | |
| 20410 | const return_ty_src = src; // TODO better source location | |
| 20411 | try sema.resolveTypeFully(block, return_ty_src, info.return_type); | |
| 20412 | }, | |
| 20354 | 20413 | else => {}, |
| 20355 | 20414 | } |
| 20356 | 20415 | } |
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/basic.zig+2-1| ... | ... | @@ -331,6 +331,7 @@ fn copy(src: *const u64, dst: *u64) void { |
| 331 | 331 | } |
| 332 | 332 | |
| 333 | 333 | test "call result of if else expression" { |
| 334 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; // stage1 has different function pointers | |
| 334 | 335 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 335 | 336 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 336 | 337 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| ... | ... | @@ -341,7 +342,7 @@ test "call result of if else expression" { |
| 341 | 342 | try expect(mem.eql(u8, f2(false), "b")); |
| 342 | 343 | } |
| 343 | 344 | fn f2(x: bool) []const u8 { |
| 344 | return (if (x) fA else fB)(); | |
| 345 | return (if (x) &fA else &fB)(); | |
| 345 | 346 | } |
| 346 | 347 | |
| 347 | 348 | test "memcpy and memset intrinsics" { |
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 { |