Skip to content

Commit b82c332

Browse files
Vexumatu3ba
authored andcommitted
fix errdefers in functions that can't return errors
This was broken by 58caed1 Closes ziglang#14053
1 parent e63cebd commit b82c332

File tree

5 files changed

+33
-2
lines changed

5 files changed

+33
-2
lines changed

src/AstGen.zig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2463,6 +2463,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
24632463
.is_non_null_ptr,
24642464
.is_non_err,
24652465
.is_non_err_ptr,
2466+
.ret_is_non_err,
24662467
.mod_rem,
24672468
.mul,
24682469
.mulwrap,
@@ -7012,7 +7013,7 @@ fn ret(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Inst.Ref
70127013

70137014
// Emit conditional branch for generating errdefers.
70147015
const result = if (ri.rl == .ptr) try gz.addUnNode(.load, ri.rl.ptr.inst, node) else operand;
7015-
const is_non_err = try gz.addUnNode(.is_non_err, result, node);
7016+
const is_non_err = try gz.addUnNode(.ret_is_non_err, result, node);
70167017
const condbr = try gz.addCondBr(.condbr, node);
70177018

70187019
var then_scope = gz.makeSubBlock(scope);

src/Sema.zig

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,7 @@ fn analyzeBodyInner(
953953
.int_type => try sema.zirIntType(block, inst),
954954
.is_non_err => try sema.zirIsNonErr(block, inst),
955955
.is_non_err_ptr => try sema.zirIsNonErrPtr(block, inst),
956+
.ret_is_non_err => try sema.zirRetIsNonErr(block, inst),
956957
.is_non_null => try sema.zirIsNonNull(block, inst),
957958
.is_non_null_ptr => try sema.zirIsNonNullPtr(block, inst),
958959
.merge_error_sets => try sema.zirMergeErrorSets(block, inst),
@@ -10288,6 +10289,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1028810289
.ret_err_value_code,
1028910290
.restore_err_ret_index,
1029010291
.is_non_err,
10292+
.ret_is_non_err,
1029110293
.condbr,
1029210294
=> {},
1029310295
else => break,
@@ -16577,7 +16579,7 @@ fn zirIsNonErr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1657716579
const src = inst_data.src();
1657816580
const operand = try sema.resolveInst(inst_data.operand);
1657916581
try sema.checkErrorType(block, src, sema.typeOf(operand));
16580-
return sema.analyzeIsNonErr(block, inst_data.src(), operand);
16582+
return sema.analyzeIsNonErr(block, src, operand);
1658116583
}
1658216584

1658316585
fn zirIsNonErrPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
@@ -16592,6 +16594,16 @@ fn zirIsNonErrPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
1659216594
return sema.analyzeIsNonErr(block, src, loaded);
1659316595
}
1659416596

16597+
fn zirRetIsNonErr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
16598+
const tracy = trace(@src());
16599+
defer tracy.end();
16600+
16601+
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
16602+
const src = inst_data.src();
16603+
const operand = try sema.resolveInst(inst_data.operand);
16604+
return sema.analyzeIsNonErr(block, src, operand);
16605+
}
16606+
1659516607
fn zirCondbr(
1659616608
sema: *Sema,
1659716609
parent_block: *Block,

src/Zir.zig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,9 @@ pub const Inst = struct {
481481
/// Return a boolean false if dereferenced pointer is an error
482482
/// Uses the `un_node` field.
483483
is_non_err_ptr,
484+
/// Same as `is_non_er` but doesn't validate that the type can be an error.
485+
/// Uses the `un_node` field.
486+
ret_is_non_err,
484487
/// A labeled block of code that loops forever. At the end of the body will have either
485488
/// a `repeat` instruction or a `repeat_inline` instruction.
486489
/// Uses the `pl_node` field. The AST node is either a for loop or while loop.
@@ -1083,6 +1086,7 @@ pub const Inst = struct {
10831086
.is_non_null_ptr,
10841087
.is_non_err,
10851088
.is_non_err_ptr,
1089+
.ret_is_non_err,
10861090
.mod_rem,
10871091
.mul,
10881092
.mulwrap,
@@ -1386,6 +1390,7 @@ pub const Inst = struct {
13861390
.is_non_null_ptr,
13871391
.is_non_err,
13881392
.is_non_err_ptr,
1393+
.ret_is_non_err,
13891394
.mod_rem,
13901395
.mul,
13911396
.mulwrap,
@@ -1640,6 +1645,7 @@ pub const Inst = struct {
16401645
.is_non_null_ptr = .un_node,
16411646
.is_non_err = .un_node,
16421647
.is_non_err_ptr = .un_node,
1648+
.ret_is_non_err = .un_node,
16431649
.loop = .pl_node,
16441650
.repeat = .node,
16451651
.repeat_inline = .node,

src/print_zir.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ const Writer = struct {
179179
.is_non_null_ptr,
180180
.is_non_err,
181181
.is_non_err_ptr,
182+
.ret_is_non_err,
182183
.typeof,
183184
.struct_init_empty,
184185
.type_info,

test/behavior/defer.zig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,3 +148,14 @@ test "simple else prong doesn't emit an error for unreachable else prong" {
148148
};
149149
try expect(a == 1);
150150
}
151+
152+
test "errdefer used in function that doesn't return an error" {
153+
const S = struct {
154+
fn foo() u8 {
155+
var a: u8 = 5;
156+
errdefer a += 1;
157+
return a;
158+
}
159+
};
160+
try expect(S.foo() == 5);
161+
}

0 commit comments

Comments
 (0)