| author | |
| committer | |
| log | 1a4b0d979027069d55ef354e6d04ea10cf455344 |
| tree | 1b983c6b5b8a18e880c4a4a9fb6c6cdf00f8a55a |
| parent | 77b40d6ecb8d04bd9d8b95b04b8ba6ce3a6ea604 |
Resolves: #158612 files changed, 43 insertions(+), 1 deletions(-)
src/AstGen.zig+17-1| ... | ... | @@ -2982,11 +2982,27 @@ fn deferStmt( |
| 2982 | 2982 | if (have_err_code) try gz.addDbgBlockEnd(); |
| 2983 | 2983 | _ = try defer_gen.addBreak(.break_inline, 0, .void_value); |
| 2984 | 2984 | |
| 2985 | // We must handle ref_table for remapped_err_code manually. | |
| 2985 | 2986 | const body = defer_gen.instructionsSlice(); |
| 2986 | const body_len = gz.astgen.countBodyLenAfterFixups(body); | |
| 2987 | const body_len = blk: { | |
| 2988 | var refs: u32 = 0; | |
| 2989 | if (have_err_code) { | |
| 2990 | var cur_inst = remapped_err_code; | |
| 2991 | while (gz.astgen.ref_table.get(cur_inst)) |ref_inst| { | |
| 2992 | refs += 1; | |
| 2993 | cur_inst = ref_inst; | |
| 2994 | } | |
| 2995 | } | |
| 2996 | break :blk gz.astgen.countBodyLenAfterFixups(body) + refs; | |
| 2997 | }; | |
| 2987 | 2998 | |
| 2988 | 2999 | const index = @intCast(u32, gz.astgen.extra.items.len); |
| 2989 | 3000 | try gz.astgen.extra.ensureUnusedCapacity(gz.astgen.gpa, body_len); |
| 3001 | if (have_err_code) { | |
| 3002 | if (gz.astgen.ref_table.fetchRemove(remapped_err_code)) |kv| { | |
| 3003 | gz.astgen.appendPossiblyRefdBodyInst(&gz.astgen.extra, kv.value); | |
| 3004 | } | |
| 3005 | } | |
| 2990 | 3006 | gz.astgen.appendBodyWithFixups(body); |
| 2991 | 3007 | |
| 2992 | 3008 | const defer_scope = try block_arena.create(Scope.Defer); |
test/behavior/defer.zig+26| ... | ... | @@ -134,6 +134,32 @@ test "errdefer with payload" { |
| 134 | 134 | comptime try S.doTheTest(); |
| 135 | 135 | } |
| 136 | 136 | |
| 137 | test "reference to errdefer payload" { | |
| 138 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | |
| 139 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 140 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 141 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | |
| 142 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | |
| 143 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | |
| 144 | ||
| 145 | const S = struct { | |
| 146 | fn foo() !i32 { | |
| 147 | errdefer |a| { | |
| 148 | const ptr = &a; | |
| 149 | const ptr2 = &ptr; | |
| 150 | expectEqual(error.One, ptr2.*.*) catch @panic("test failure"); | |
| 151 | expectEqual(error.One, ptr.*) catch @panic("test failure"); | |
| 152 | } | |
| 153 | return error.One; | |
| 154 | } | |
| 155 | fn doTheTest() !void { | |
| 156 | try expectError(error.One, foo()); | |
| 157 | } | |
| 158 | }; | |
| 159 | try S.doTheTest(); | |
| 160 | comptime try S.doTheTest(); | |
| 161 | } | |
| 162 | ||
| 137 | 163 | test "simple else prong doesn't emit an error for unreachable else prong" { |
| 138 | 164 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 139 | 165 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |