| 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,7 +753,7 @@ pub fn default_panic(msg: []const u8, error_return_trace: ?*StackTrace) noreturn |
| 753 | @setCold(true); | 753 | @setCold(true); |
| 754 | // Until self-hosted catches up with stage1 language features, we have a simpler | 754 | // Until self-hosted catches up with stage1 language features, we have a simpler |
| 755 | // default panic function: | 755 | // default panic function: |
| 756 | if (builtin.zig_backend != .stage1) { | 756 | if (builtin.zig_backend != .stage1 and builtin.zig_backend != .stage2_llvm) { |
| 757 | while (true) { | 757 | while (true) { |
| 758 | @breakpoint(); | 758 | @breakpoint(); |
| 759 | } | 759 | } |
lib/std/c/darwin.zig+10-6| ... | @@ -624,8 +624,7 @@ pub const pthread_attr_t = extern struct { | ... | @@ -624,8 +624,7 @@ pub const pthread_attr_t = extern struct { |
| 624 | __opaque: [56]u8, | 624 | __opaque: [56]u8, |
| 625 | }; | 625 | }; |
| 626 | 626 | ||
| 627 | const pthread_t = std.c.pthread_t; | 627 | pub extern "c" fn pthread_threadid_np(thread: ?std.c.pthread_t, thread_id: *u64) c_int; |
| 628 | pub extern "c" fn pthread_threadid_np(thread: ?pthread_t, thread_id: *u64) c_int; | ||
| 629 | pub extern "c" fn pthread_setname_np(name: [*:0]const u8) E; | 628 | pub extern "c" fn pthread_setname_np(name: [*:0]const u8) E; |
| 630 | pub extern "c" fn pthread_getname_np(thread: std.c.pthread_t, name: [*:0]u8, len: usize) E; | 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,12 +920,17 @@ pub const siginfo_t = extern struct { |
| 921 | 920 | ||
| 922 | /// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name. | 921 | /// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name. |
| 923 | pub const Sigaction = extern struct { | 922 | pub const Sigaction = extern struct { |
| 924 | pub const handler_fn = fn (c_int) callconv(.C) void; | 923 | pub usingnamespace if (builtin.zig_backend == .stage1) struct { |
| 925 | pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const anyopaque) callconv(.C) void; | 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 | handler: extern union { | 931 | handler: extern union { |
| 928 | handler: ?handler_fn, | 932 | handler: ?Sigaction.handler_fn, |
| 929 | sigaction: ?sigaction_fn, | 933 | sigaction: ?Sigaction.sigaction_fn, |
| 930 | }, | 934 | }, |
| 931 | mask: sigset_t, | 935 | mask: sigset_t, |
| 932 | flags: c_uint, | 936 | flags: c_uint, |
lib/std/debug.zig-1| ... | @@ -1541,7 +1541,6 @@ pub const ModuleDebugInfo = switch (native_os) { | ... | @@ -1541,7 +1541,6 @@ pub const ModuleDebugInfo = switch (native_os) { |
| 1541 | .symbol_name = o_file_di.getSymbolName(relocated_address_o) orelse "???", | 1541 | .symbol_name = o_file_di.getSymbolName(relocated_address_o) orelse "???", |
| 1542 | .compile_unit_name = compile_unit.die.getAttrString(o_file_di, DW.AT.name) catch |err| switch (err) { | 1542 | .compile_unit_name = compile_unit.die.getAttrString(o_file_di, DW.AT.name) catch |err| switch (err) { |
| 1543 | error.MissingDebugInfo, error.InvalidDebugInfo => "???", | 1543 | error.MissingDebugInfo, error.InvalidDebugInfo => "???", |
| 1544 | else => return err, | ||
| 1545 | }, | 1544 | }, |
| 1546 | .line_info = o_file_di.getLineNumberInfo(compile_unit.*, relocated_address_o + addr_off) catch |err| switch (err) { | 1545 | .line_info = o_file_di.getLineNumberInfo(compile_unit.*, relocated_address_o + addr_off) catch |err| switch (err) { |
| 1547 | error.MissingDebugInfo, error.InvalidDebugInfo => null, | 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,15 +341,9 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 341 | const slot_index = @intCast(SlotIndex, used_bits_byte * 8 + bit_index); | 341 | const slot_index = @intCast(SlotIndex, used_bits_byte * 8 + bit_index); |
| 342 | const stack_trace = bucketStackTrace(bucket, size_class, slot_index, .alloc); | 342 | const stack_trace = bucketStackTrace(bucket, size_class, slot_index, .alloc); |
| 343 | const addr = bucket.page + slot_index * size_class; | 343 | const addr = bucket.page + slot_index * size_class; |
| 344 | if (builtin.zig_backend == .stage1) { | 344 | log.err("memory address 0x{x} leaked: {s}", .{ |
| 345 | log.err("memory address 0x{x} leaked: {s}", .{ | 345 | @ptrToInt(addr), stack_trace, |
| 346 | @ptrToInt(addr), stack_trace, | 346 | }); |
| 347 | }); | ||
| 348 | } else { // TODO | ||
| 349 | log.err("memory address 0x{x} leaked", .{ | ||
| 350 | @ptrToInt(addr), | ||
| 351 | }); | ||
| 352 | } | ||
| 353 | leaks = true; | 347 | leaks = true; |
| 354 | } | 348 | } |
| 355 | if (bit_index == math.maxInt(u3)) | 349 | if (bit_index == math.maxInt(u3)) |
| ... | @@ -379,15 +373,9 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { | ... | @@ -379,15 +373,9 @@ pub fn GeneralPurposeAllocator(comptime config: Config) type { |
| 379 | while (it.next()) |large_alloc| { | 373 | while (it.next()) |large_alloc| { |
| 380 | if (config.retain_metadata and large_alloc.freed) continue; | 374 | if (config.retain_metadata and large_alloc.freed) continue; |
| 381 | const stack_trace = large_alloc.getStackTrace(.alloc); | 375 | const stack_trace = large_alloc.getStackTrace(.alloc); |
| 382 | if (builtin.zig_backend == .stage1) { | 376 | log.err("memory address 0x{x} leaked: {s}", .{ |
| 383 | log.err("memory address 0x{x} leaked: {s}", .{ | 377 | @ptrToInt(large_alloc.bytes.ptr), stack_trace, |
| 384 | @ptrToInt(large_alloc.bytes.ptr), stack_trace, | 378 | }); |
| 385 | }); | ||
| 386 | } else { // TODO | ||
| 387 | log.err("memory address 0x{x} leaked", .{ | ||
| 388 | @ptrToInt(large_alloc.bytes.ptr), | ||
| 389 | }); | ||
| 390 | } | ||
| 391 | leaks = true; | 379 | leaks = true; |
| 392 | } | 380 | } |
| 393 | return leaks; | 381 | return leaks; |
lib/std/macho.zig+3-1| ... | @@ -624,7 +624,9 @@ pub const segment_command_64 = extern struct { | ... | @@ -624,7 +624,9 @@ pub const segment_command_64 = extern struct { |
| 624 | cmd: LC = .SEGMENT_64, | 624 | cmd: LC = .SEGMENT_64, |
| 625 | 625 | ||
| 626 | /// includes sizeof section_64 structs | 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 | /// segment name | 631 | /// segment name |
| 630 | segname: [16]u8, | 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,12 +1080,19 @@ pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigact |
| 1080 | const mask_size = @sizeOf(@TypeOf(ksa.mask)); | 1080 | const mask_size = @sizeOf(@TypeOf(ksa.mask)); |
| 1081 | 1081 | ||
| 1082 | if (act) |new| { | 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 | ksa = k_sigaction{ | 1091 | ksa = k_sigaction{ |
| 1085 | .handler = new.handler.handler, | 1092 | .handler = new.handler.handler, |
| 1086 | .flags = new.flags | SA.RESTORER, | 1093 | .flags = new.flags | SA.RESTORER, |
| 1087 | .mask = undefined, | 1094 | .mask = undefined, |
| 1088 | .restorer = @ptrCast(fn () callconv(.C) void, restorer_fn), | 1095 | .restorer = @ptrCast(k_sigaction_funcs.restorer, restorer_fn), |
| 1089 | }; | 1096 | }; |
| 1090 | @memcpy(@ptrCast([*]u8, &ksa.mask), @ptrCast([*]const u8, &new.mask), mask_size); | 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,39 +3054,55 @@ pub const sigset_t = [1024 / 32]u32; |
| 3047 | pub const all_mask: sigset_t = [_]u32{0xffffffff} ** sigset_t.len; | 3054 | pub const all_mask: sigset_t = [_]u32{0xffffffff} ** sigset_t.len; |
| 3048 | pub const app_mask: sigset_t = [2]u32{ 0xfffffffc, 0x7fffffff } ++ [_]u32{0xffffffff} ** 30; | 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 | pub const k_sigaction = switch (native_arch) { | 3065 | pub const k_sigaction = switch (native_arch) { |
| 3051 | .mips, .mipsel => extern struct { | 3066 | .mips, .mipsel => extern struct { |
| 3052 | flags: c_uint, | 3067 | flags: c_uint, |
| 3053 | handler: ?fn (c_int) callconv(.C) void, | 3068 | handler: k_sigaction_funcs.handler, |
| 3054 | mask: [4]c_ulong, | 3069 | mask: [4]c_ulong, |
| 3055 | restorer: fn () callconv(.C) void, | 3070 | restorer: k_sigaction_funcs.restorer, |
| 3056 | }, | 3071 | }, |
| 3057 | .mips64, .mips64el => extern struct { | 3072 | .mips64, .mips64el => extern struct { |
| 3058 | flags: c_uint, | 3073 | flags: c_uint, |
| 3059 | handler: ?fn (c_int) callconv(.C) void, | 3074 | handler: k_sigaction_funcs.handler, |
| 3060 | mask: [2]c_ulong, | 3075 | mask: [2]c_ulong, |
| 3061 | restorer: fn () callconv(.C) void, | 3076 | restorer: k_sigaction_funcs.restorer, |
| 3062 | }, | 3077 | }, |
| 3063 | else => extern struct { | 3078 | else => extern struct { |
| 3064 | handler: ?fn (c_int) callconv(.C) void, | 3079 | handler: k_sigaction_funcs.handler, |
| 3065 | flags: c_ulong, | 3080 | flags: c_ulong, |
| 3066 | restorer: fn () callconv(.C) void, | 3081 | restorer: k_sigaction_funcs.restorer, |
| 3067 | mask: [2]c_uint, | 3082 | mask: [2]c_uint, |
| 3068 | }, | 3083 | }, |
| 3069 | }; | 3084 | }; |
| 3070 | 3085 | ||
| 3071 | /// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall. | 3086 | /// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall. |
| 3072 | pub const Sigaction = extern struct { | 3087 | pub const Sigaction = extern struct { |
| 3073 | pub const handler_fn = fn (c_int) callconv(.C) void; | 3088 | pub usingnamespace if (builtin.zig_backend == .stage1) struct { |
| 3074 | pub const sigaction_fn = fn (c_int, *const siginfo_t, ?*const anyopaque) callconv(.C) void; | 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 | handler: extern union { | 3096 | handler: extern union { |
| 3077 | handler: ?handler_fn, | 3097 | handler: ?Sigaction.handler_fn, |
| 3078 | sigaction: ?sigaction_fn, | 3098 | sigaction: ?Sigaction.sigaction_fn, |
| 3079 | }, | 3099 | }, |
| 3080 | mask: sigset_t, | 3100 | mask: sigset_t, |
| 3081 | flags: c_uint, | 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 | pub const empty_sigset = [_]u32{0} ** @typeInfo(sigset_t).Array.len; | 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,6 +131,9 @@ pub const Block = struct { |
| 131 | 131 | ||
| 132 | c_import_buf: ?*std.ArrayList(u8) = null, | 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 | const Param = struct { | 137 | const Param = struct { |
| 135 | /// `noreturn` means `anytype`. | 138 | /// `noreturn` means `anytype`. |
| 136 | ty: Type, | 139 | ty: Type, |
| ... | @@ -189,6 +192,7 @@ pub const Block = struct { | ... | @@ -189,6 +192,7 @@ pub const Block = struct { |
| 189 | .runtime_index = parent.runtime_index, | 192 | .runtime_index = parent.runtime_index, |
| 190 | .want_safety = parent.want_safety, | 193 | .want_safety = parent.want_safety, |
| 191 | .c_import_buf = parent.c_import_buf, | 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,6 +3934,23 @@ fn analyzeBlockBody( |
| 3930 | // to emit a jump instruction to after the block when it encounters the break. | 3934 | // to emit a jump instruction to after the block when it encounters the break. |
| 3931 | try parent_block.instructions.append(gpa, merges.block_inst); | 3935 | try parent_block.instructions.append(gpa, merges.block_inst); |
| 3932 | const resolved_ty = try sema.resolvePeerTypes(parent_block, src, merges.results.items, .none); | 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 | const ty_inst = try sema.addType(resolved_ty); | 3954 | const ty_inst = try sema.addType(resolved_ty); |
| 3934 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + | 3955 | try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).Struct.fields.len + |
| 3935 | child_block.instructions.items.len); | 3956 | child_block.instructions.items.len); |
| ... | @@ -4191,6 +4212,11 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -4191,6 +4212,11 @@ fn zirBreak(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) CompileError |
| 4191 | const br_ref = try start_block.addBr(label.merges.block_inst, operand); | 4212 | const br_ref = try start_block.addBr(label.merges.block_inst, operand); |
| 4192 | try label.merges.results.append(sema.gpa, operand); | 4213 | try label.merges.results.append(sema.gpa, operand); |
| 4193 | try label.merges.br_list.append(sema.gpa, Air.refToIndex(br_ref).?); | 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 | return inst; | 4220 | return inst; |
| 4195 | } | 4221 | } |
| 4196 | } | 4222 | } |
| ... | @@ -6692,12 +6718,6 @@ fn zirSwitchCapture( | ... | @@ -6692,12 +6718,6 @@ fn zirSwitchCapture( |
| 6692 | 6718 | ||
| 6693 | if (capture_info.prong_index == std.math.maxInt(@TypeOf(capture_info.prong_index))) { | 6719 | if (capture_info.prong_index == std.math.maxInt(@TypeOf(capture_info.prong_index))) { |
| 6694 | // It is the else/`_` prong. | 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 | if (is_ref) { | 6721 | if (is_ref) { |
| 6702 | assert(operand_is_ref); | 6722 | assert(operand_is_ref); |
| 6703 | return operand_ptr; | 6723 | return operand_ptr; |
| ... | @@ -6708,7 +6728,10 @@ fn zirSwitchCapture( | ... | @@ -6708,7 +6728,10 @@ fn zirSwitchCapture( |
| 6708 | else | 6728 | else |
| 6709 | operand_ptr; | 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 | if (is_multi) { | 6737 | if (is_multi) { |
| ... | @@ -6885,6 +6908,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -6885,6 +6908,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 6885 | 6908 | ||
| 6886 | const operand_ty = sema.typeOf(operand); | 6909 | const operand_ty = sema.typeOf(operand); |
| 6887 | 6910 | ||
| 6911 | var else_error_ty: ?Type = null; | ||
| 6912 | |||
| 6888 | // Validate usage of '_' prongs. | 6913 | // Validate usage of '_' prongs. |
| 6889 | if (special_prong == .under and !operand_ty.isNonexhaustiveEnum()) { | 6914 | if (special_prong == .under and !operand_ty.isNonexhaustiveEnum()) { |
| 6890 | const msg = msg: { | 6915 | const msg = msg: { |
| ... | @@ -7077,6 +7102,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -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 | } else { | 7106 | } else { |
| 7081 | var maybe_msg: ?*Module.ErrorMsg = null; | 7107 | var maybe_msg: ?*Module.ErrorMsg = null; |
| 7082 | errdefer if (maybe_msg) |msg| msg.destroy(sema.gpa); | 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,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 | .Union => return sema.fail(block, src, "TODO validate switch .Union", .{}), | 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,6 +7435,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 7398 | .label = &label, | 7435 | .label = &label, |
| 7399 | .inlining = block.inlining, | 7436 | .inlining = block.inlining, |
| 7400 | .is_comptime = block.is_comptime, | 7437 | .is_comptime = block.is_comptime, |
| 7438 | .switch_else_err_ty = else_error_ty, | ||
| 7401 | }; | 7439 | }; |
| 7402 | const merges = &child_block.label.?.merges; | 7440 | const merges = &child_block.label.?.merges; |
| 7403 | defer child_block.instructions.deinit(gpa); | 7441 | defer child_block.instructions.deinit(gpa); |
| ... | @@ -15447,6 +15485,26 @@ fn validateVarType( | ... | @@ -15447,6 +15485,26 @@ fn validateVarType( |
| 15447 | var_ty: Type, | 15485 | var_ty: Type, |
| 15448 | is_extern: bool, | 15486 | is_extern: bool, |
| 15449 | ) CompileError!void { | 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 | var ty = var_ty; | 15508 | var ty = var_ty; |
| 15451 | while (true) switch (ty.zigTypeTag()) { | 15509 | while (true) switch (ty.zigTypeTag()) { |
| 15452 | .Bool, | 15510 | .Bool, |
| ... | @@ -15457,7 +15515,7 @@ fn validateVarType( | ... | @@ -15457,7 +15515,7 @@ fn validateVarType( |
| 15457 | .Frame, | 15515 | .Frame, |
| 15458 | .AnyFrame, | 15516 | .AnyFrame, |
| 15459 | .Void, | 15517 | .Void, |
| 15460 | => return, | 15518 | => return true, |
| 15461 | 15519 | ||
| 15462 | .BoundFn, | 15520 | .BoundFn, |
| 15463 | .ComptimeFloat, | 15521 | .ComptimeFloat, |
| ... | @@ -15468,21 +15526,21 @@ fn validateVarType( | ... | @@ -15468,21 +15526,21 @@ fn validateVarType( |
| 15468 | .Undefined, | 15526 | .Undefined, |
| 15469 | .Null, | 15527 | .Null, |
| 15470 | .Fn, | 15528 | .Fn, |
| 15471 | => break, | 15529 | => return false, |
| 15472 | 15530 | ||
| 15473 | .Pointer => { | 15531 | .Pointer => { |
| 15474 | const elem_ty = ty.childType(); | 15532 | const elem_ty = ty.childType(); |
| 15475 | switch (elem_ty.zigTypeTag()) { | 15533 | switch (elem_ty.zigTypeTag()) { |
| 15476 | .Opaque, .Fn => return, | 15534 | .Opaque, .Fn => return true, |
| 15477 | else => ty = elem_ty, | 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 | .Optional => { | 15540 | .Optional => { |
| 15483 | var buf: Type.Payload.ElemType = undefined; | 15541 | var buf: Type.Payload.ElemType = undefined; |
| 15484 | const child_ty = ty.optionalChild(&buf); | 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 | .Array, .Vector => ty = ty.elemType(), | 15545 | .Array, .Vector => ty = ty.elemType(), |
| 15488 | 15546 | ||
| ... | @@ -15490,23 +15548,10 @@ fn validateVarType( | ... | @@ -15490,23 +15548,10 @@ fn validateVarType( |
| 15490 | 15548 | ||
| 15491 | .Struct, .Union => { | 15549 | .Struct, .Union => { |
| 15492 | const resolved_ty = try sema.resolveTypeFields(block, src, ty); | 15550 | const resolved_ty = try sema.resolveTypeFields(block, src, ty); |
| 15493 | if (try sema.typeRequiresComptime(block, src, resolved_ty)) { | 15551 | const needs_comptime = try sema.typeRequiresComptime(block, src, resolved_ty); |
| 15494 | break; | 15552 | return !needs_comptime; |
| 15495 | } else { | ||
| 15496 | return; | ||
| 15497 | } | ||
| 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 | fn explainWhyTypeIsComptime( | 15557 | fn explainWhyTypeIsComptime( |
| ... | @@ -18494,8 +18539,8 @@ pub fn bitCastVal( | ... | @@ -18494,8 +18539,8 @@ pub fn bitCastVal( |
| 18494 | const abi_size = try sema.usizeCast(block, src, old_ty.abiSize(target)); | 18539 | const abi_size = try sema.usizeCast(block, src, old_ty.abiSize(target)); |
| 18495 | const buffer = try sema.gpa.alloc(u8, abi_size); | 18540 | const buffer = try sema.gpa.alloc(u8, abi_size); |
| 18496 | defer sema.gpa.free(buffer); | 18541 | defer sema.gpa.free(buffer); |
| 18497 | val.writeToMemory(old_ty, target, buffer); | 18542 | val.writeToMemory(old_ty, sema.mod, buffer); |
| 18498 | return Value.readFromMemory(new_ty, target, buffer[buffer_offset..], sema.arena); | 18543 | return Value.readFromMemory(new_ty, sema.mod, buffer[buffer_offset..], sema.arena); |
| 18499 | } | 18544 | } |
| 18500 | 18545 | ||
| 18501 | fn coerceArrayPtrToSlice( | 18546 | fn coerceArrayPtrToSlice( |
| ... | @@ -20351,6 +20396,20 @@ pub fn resolveTypeFully( | ... | @@ -20351,6 +20396,20 @@ pub fn resolveTypeFully( |
| 20351 | return resolveTypeFully(sema, block, src, ty.optionalChild(&buf)); | 20396 | return resolveTypeFully(sema, block, src, ty.optionalChild(&buf)); |
| 20352 | }, | 20397 | }, |
| 20353 | .ErrorUnion => return resolveTypeFully(sema, block, src, ty.errorUnionPayload()), | 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 | else => {}, | 20413 | else => {}, |
| 20355 | } | 20414 | } |
| 20356 | } | 20415 | } |
src/link/MachO.zig+5| ... | @@ -4301,6 +4301,7 @@ fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4301,6 +4301,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 4301 | .inner = .{ | 4301 | .inner = .{ |
| 4302 | .segname = makeStaticString("__PAGEZERO"), | 4302 | .segname = makeStaticString("__PAGEZERO"), |
| 4303 | .vmsize = pagezero_vmsize, | 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,6 +4327,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 4326 | .filesize = needed_size, | 4327 | .filesize = needed_size, |
| 4327 | .maxprot = macho.PROT.READ | macho.PROT.EXEC, | 4328 | .maxprot = macho.PROT.READ | macho.PROT.EXEC, |
| 4328 | .initprot = macho.PROT.READ | macho.PROT.EXEC, | 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,6 +4433,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 4431 | .filesize = needed_size, | 4433 | .filesize = needed_size, |
| 4432 | .maxprot = macho.PROT.READ | macho.PROT.WRITE, | 4434 | .maxprot = macho.PROT.READ | macho.PROT.WRITE, |
| 4433 | .initprot = macho.PROT.READ | macho.PROT.WRITE, | 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,6 +4483,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 4480 | .filesize = needed_size, | 4483 | .filesize = needed_size, |
| 4481 | .maxprot = macho.PROT.READ | macho.PROT.WRITE, | 4484 | .maxprot = macho.PROT.READ | macho.PROT.WRITE, |
| 4482 | .initprot = macho.PROT.READ | macho.PROT.WRITE, | 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,6 +4593,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 4589 | .fileoff = fileoff, | 4593 | .fileoff = fileoff, |
| 4590 | .maxprot = macho.PROT.READ, | 4594 | .maxprot = macho.PROT.READ, |
| 4591 | .initprot = macho.PROT.READ, | 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,6 +148,7 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: Allocator) !void |
| 148 | .vmsize = needed_size, | 148 | .vmsize = needed_size, |
| 149 | .fileoff = fileoff, | 149 | .fileoff = fileoff, |
| 150 | .filesize = needed_size, | 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,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 | if (val.isUndef()) { | 1047 | if (val.isUndef()) { |
| 1047 | const size = @intCast(usize, ty.abiSize(target)); | 1048 | const size = @intCast(usize, ty.abiSize(target)); |
| 1048 | std.mem.set(u8, buffer[0..size], 0xaa); | 1049 | std.mem.set(u8, buffer[0..size], 0xaa); |
| ... | @@ -1081,7 +1082,7 @@ pub const Value = extern union { | ... | @@ -1081,7 +1082,7 @@ pub const Value = extern union { |
| 1081 | var buf_off: usize = 0; | 1082 | var buf_off: usize = 0; |
| 1082 | while (elem_i < len) : (elem_i += 1) { | 1083 | while (elem_i < len) : (elem_i += 1) { |
| 1083 | const elem_val = val.elemValueBuffer(elem_i, &elem_value_buf); | 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 | buf_off += elem_size; | 1086 | buf_off += elem_size; |
| 1086 | } | 1087 | } |
| 1087 | }, | 1088 | }, |
| ... | @@ -1092,7 +1093,7 @@ pub const Value = extern union { | ... | @@ -1092,7 +1093,7 @@ pub const Value = extern union { |
| 1092 | const field_vals = val.castTag(.aggregate).?.data; | 1093 | const field_vals = val.castTag(.aggregate).?.data; |
| 1093 | for (fields) |field, i| { | 1094 | for (fields) |field, i| { |
| 1094 | const off = @intCast(usize, ty.structFieldOffset(i, target)); | 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 | .Packed => { | 1099 | .Packed => { |
| ... | @@ -1105,6 +1106,12 @@ pub const Value = extern union { | ... | @@ -1105,6 +1106,12 @@ pub const Value = extern union { |
| 1105 | host_int.writeTwosComplement(buffer, bit_size, abi_size, target.cpu.arch.endian()); | 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 | else => @panic("TODO implement writeToMemory for more types"), | 1115 | else => @panic("TODO implement writeToMemory for more types"), |
| 1109 | } | 1116 | } |
| 1110 | } | 1117 | } |
| ... | @@ -1153,10 +1160,11 @@ pub const Value = extern union { | ... | @@ -1153,10 +1160,11 @@ pub const Value = extern union { |
| 1153 | 1160 | ||
| 1154 | pub fn readFromMemory( | 1161 | pub fn readFromMemory( |
| 1155 | ty: Type, | 1162 | ty: Type, |
| 1156 | target: Target, | 1163 | mod: *Module, |
| 1157 | buffer: []const u8, | 1164 | buffer: []const u8, |
| 1158 | arena: Allocator, | 1165 | arena: Allocator, |
| 1159 | ) Allocator.Error!Value { | 1166 | ) Allocator.Error!Value { |
| 1167 | const target = mod.getTarget(); | ||
| 1160 | switch (ty.zigTypeTag()) { | 1168 | switch (ty.zigTypeTag()) { |
| 1161 | .Int => { | 1169 | .Int => { |
| 1162 | if (buffer.len == 0) return Value.zero; | 1170 | if (buffer.len == 0) return Value.zero; |
| ... | @@ -1184,7 +1192,7 @@ pub const Value = extern union { | ... | @@ -1184,7 +1192,7 @@ pub const Value = extern union { |
| 1184 | const elems = try arena.alloc(Value, @intCast(usize, ty.arrayLen())); | 1192 | const elems = try arena.alloc(Value, @intCast(usize, ty.arrayLen())); |
| 1185 | var offset: usize = 0; | 1193 | var offset: usize = 0; |
| 1186 | for (elems) |*elem| { | 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 | offset += @intCast(usize, elem_size); | 1196 | offset += @intCast(usize, elem_size); |
| 1189 | } | 1197 | } |
| 1190 | return Tag.aggregate.create(arena, elems); | 1198 | return Tag.aggregate.create(arena, elems); |
| ... | @@ -1196,7 +1204,7 @@ pub const Value = extern union { | ... | @@ -1196,7 +1204,7 @@ pub const Value = extern union { |
| 1196 | const field_vals = try arena.alloc(Value, fields.len); | 1204 | const field_vals = try arena.alloc(Value, fields.len); |
| 1197 | for (fields) |field, i| { | 1205 | for (fields) |field, i| { |
| 1198 | const off = @intCast(usize, ty.structFieldOffset(i, target)); | 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 | return Tag.aggregate.create(arena, field_vals); | 1209 | return Tag.aggregate.create(arena, field_vals); |
| 1202 | }, | 1210 | }, |
| ... | @@ -1212,6 +1220,18 @@ pub const Value = extern union { | ... | @@ -1212,6 +1220,18 @@ pub const Value = extern union { |
| 1212 | return intToPackedStruct(ty, target, bigint.toConst(), arena); | 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 | else => @panic("TODO implement readFromMemory for more types"), | 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,6 +331,7 @@ fn copy(src: *const u64, dst: *u64) void { |
| 331 | } | 331 | } |
| 332 | 332 | ||
| 333 | test "call result of if else expression" { | 333 | test "call result of if else expression" { |
| 334 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; // stage1 has different function pointers | ||
| 334 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 335 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 335 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 336 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 336 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 337 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| ... | @@ -341,7 +342,7 @@ test "call result of if else expression" { | ... | @@ -341,7 +342,7 @@ test "call result of if else expression" { |
| 341 | try expect(mem.eql(u8, f2(false), "b")); | 342 | try expect(mem.eql(u8, f2(false), "b")); |
| 342 | } | 343 | } |
| 343 | fn f2(x: bool) []const u8 { | 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 | test "memcpy and memset intrinsics" { | 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,7 +430,11 @@ test "switch on integer with else capturing expr" { |
| 430 | } | 430 | } |
| 431 | 431 | ||
| 432 | test "else prong of switch on error set excludes other cases" { | 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 | const S = struct { | 439 | const S = struct { |
| 436 | fn doTheTest() !void { | 440 | fn doTheTest() !void { |