Commit 1a4b0d9790
Changed files (2)
src
test
behavior
src/AstGen.zig
@@ -2982,11 +2982,27 @@ fn deferStmt(
if (have_err_code) try gz.addDbgBlockEnd();
_ = try defer_gen.addBreak(.break_inline, 0, .void_value);
+ // We must handle ref_table for remapped_err_code manually.
const body = defer_gen.instructionsSlice();
- const body_len = gz.astgen.countBodyLenAfterFixups(body);
+ const body_len = blk: {
+ var refs: u32 = 0;
+ if (have_err_code) {
+ var cur_inst = remapped_err_code;
+ while (gz.astgen.ref_table.get(cur_inst)) |ref_inst| {
+ refs += 1;
+ cur_inst = ref_inst;
+ }
+ }
+ break :blk gz.astgen.countBodyLenAfterFixups(body) + refs;
+ };
const index = @intCast(u32, gz.astgen.extra.items.len);
try gz.astgen.extra.ensureUnusedCapacity(gz.astgen.gpa, body_len);
+ if (have_err_code) {
+ if (gz.astgen.ref_table.fetchRemove(remapped_err_code)) |kv| {
+ gz.astgen.appendPossiblyRefdBodyInst(&gz.astgen.extra, kv.value);
+ }
+ }
gz.astgen.appendBodyWithFixups(body);
const defer_scope = try block_arena.create(Scope.Defer);
test/behavior/defer.zig
@@ -134,6 +134,32 @@ test "errdefer with payload" {
comptime try S.doTheTest();
}
+test "reference to errdefer payload" {
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn foo() !i32 {
+ errdefer |a| {
+ const ptr = &a;
+ const ptr2 = &ptr;
+ expectEqual(error.One, ptr2.*.*) catch @panic("test failure");
+ expectEqual(error.One, ptr.*) catch @panic("test failure");
+ }
+ return error.One;
+ }
+ fn doTheTest() !void {
+ try expectError(error.One, foo());
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
test "simple else prong doesn't emit an error for unreachable else prong" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO