| ... | ... | @@ -3091,7 +3091,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t |
| 3091 | 3091 | static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { |
| 3092 | 3092 | results[ReturnKindUnconditional] = 0; |
| 3093 | 3093 | results[ReturnKindError] = 0; |
| 3094 | | results[ReturnKindMaybe] = 0; |
| 3095 | 3094 | |
| 3096 | 3095 | while (inner_scope != outer_scope) { |
| 3097 | 3096 | assert(inner_scope); |
| ... | ... | @@ -3111,9 +3110,7 @@ static IrInstruction *ir_mark_gen(IrInstruction *instruction) { |
| 3111 | 3110 | return instruction; |
| 3112 | 3111 | } |
| 3113 | 3112 | |
| 3114 | | static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, |
| 3115 | | bool gen_error_defers, bool gen_maybe_defers) |
| 3116 | | { |
| 3113 | static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, bool gen_error_defers) { |
| 3117 | 3114 | Scope *scope = inner_scope; |
| 3118 | 3115 | while (scope != outer_scope) { |
| 3119 | 3116 | if (!scope) |
| ... | ... | @@ -3124,8 +3121,7 @@ static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *o |
| 3124 | 3121 | assert(defer_node->type == NodeTypeDefer); |
| 3125 | 3122 | ReturnKind defer_kind = defer_node->data.defer.kind; |
| 3126 | 3123 | if (defer_kind == ReturnKindUnconditional || |
| 3127 | | (gen_error_defers && defer_kind == ReturnKindError) || |
| 3128 | | (gen_maybe_defers && defer_kind == ReturnKindMaybe)) |
| 3124 | (gen_error_defers && defer_kind == ReturnKindError)) |
| 3129 | 3125 | { |
| 3130 | 3126 | AstNode *defer_expr_node = defer_node->data.defer.expr; |
| 3131 | 3127 | ir_gen_node(irb, defer_expr_node, defer_node->data.defer.expr_scope); |
| ... | ... | @@ -3188,7 +3184,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3188 | 3184 | return_value = ir_build_const_void(irb, scope, node); |
| 3189 | 3185 | } |
| 3190 | 3186 | |
| 3191 | | size_t defer_counts[3]; |
| 3187 | size_t defer_counts[2]; |
| 3192 | 3188 | ir_count_defers(irb, scope, outer_scope, defer_counts); |
| 3193 | 3189 | if (defer_counts[ReturnKindError] > 0) { |
| 3194 | 3190 | IrBasicBlock *err_block = ir_build_basic_block(irb, scope, "ErrRetErr"); |
| ... | ... | @@ -3206,37 +3202,15 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3206 | 3202 | ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, is_comptime)); |
| 3207 | 3203 | |
| 3208 | 3204 | ir_set_cursor_at_end(irb, err_block); |
| 3209 | | ir_gen_defers_for_block(irb, scope, outer_scope, true, false); |
| 3210 | | ir_build_return(irb, scope, node, return_value); |
| 3211 | | |
| 3212 | | ir_set_cursor_at_end(irb, ok_block); |
| 3213 | | ir_gen_defers_for_block(irb, scope, outer_scope, false, false); |
| 3214 | | return ir_build_return(irb, scope, node, return_value); |
| 3215 | | } else if (defer_counts[ReturnKindMaybe] > 0) { |
| 3216 | | IrBasicBlock *null_block = ir_build_basic_block(irb, scope, "MaybeRetNull"); |
| 3217 | | IrBasicBlock *ok_block = ir_build_basic_block(irb, scope, "MaybeRetOk"); |
| 3218 | | |
| 3219 | | IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node, return_value); |
| 3220 | | |
| 3221 | | IrInstruction *is_comptime; |
| 3222 | | if (ir_should_inline(irb->exec, scope)) { |
| 3223 | | is_comptime = ir_build_const_bool(irb, scope, node, true); |
| 3224 | | } else { |
| 3225 | | is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null); |
| 3226 | | } |
| 3227 | | |
| 3228 | | ir_mark_gen(ir_build_cond_br(irb, scope, node, is_non_null, ok_block, null_block, is_comptime)); |
| 3229 | | |
| 3230 | | ir_set_cursor_at_end(irb, null_block); |
| 3231 | | ir_gen_defers_for_block(irb, scope, outer_scope, false, true); |
| 3205 | ir_gen_defers_for_block(irb, scope, outer_scope, true); |
| 3232 | 3206 | ir_build_return(irb, scope, node, return_value); |
| 3233 | 3207 | |
| 3234 | 3208 | ir_set_cursor_at_end(irb, ok_block); |
| 3235 | | ir_gen_defers_for_block(irb, scope, outer_scope, false, false); |
| 3209 | ir_gen_defers_for_block(irb, scope, outer_scope, false); |
| 3236 | 3210 | return ir_build_return(irb, scope, node, return_value); |
| 3237 | 3211 | } else { |
| 3238 | 3212 | // generate unconditional defers |
| 3239 | | ir_gen_defers_for_block(irb, scope, outer_scope, false, false); |
| 3213 | ir_gen_defers_for_block(irb, scope, outer_scope, false); |
| 3240 | 3214 | return ir_build_return(irb, scope, node, return_value); |
| 3241 | 3215 | } |
| 3242 | 3216 | } |
| ... | ... | @@ -3255,7 +3229,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3255 | 3229 | ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err_val, return_block, continue_block, is_comptime)); |
| 3256 | 3230 | |
| 3257 | 3231 | ir_set_cursor_at_end(irb, return_block); |
| 3258 | | ir_gen_defers_for_block(irb, scope, outer_scope, true, false); |
| 3232 | ir_gen_defers_for_block(irb, scope, outer_scope, true); |
| 3259 | 3233 | IrInstruction *err_val = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr); |
| 3260 | 3234 | ir_build_return(irb, scope, node, err_val); |
| 3261 | 3235 | |
| ... | ... | @@ -3266,32 +3240,6 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 3266 | 3240 | else |
| 3267 | 3241 | return ir_build_load_ptr(irb, scope, node, unwrapped_ptr); |
| 3268 | 3242 | } |
| 3269 | | case ReturnKindMaybe: |
| 3270 | | { |
| 3271 | | assert(expr_node); |
| 3272 | | IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LVAL_PTR); |
| 3273 | | if (maybe_val_ptr == irb->codegen->invalid_instruction) |
| 3274 | | return irb->codegen->invalid_instruction; |
| 3275 | | IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node, maybe_val_ptr); |
| 3276 | | IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node, maybe_val); |
| 3277 | | |
| 3278 | | IrBasicBlock *return_block = ir_build_basic_block(irb, scope, "MaybeRetReturn"); |
| 3279 | | IrBasicBlock *continue_block = ir_build_basic_block(irb, scope, "MaybeRetContinue"); |
| 3280 | | IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, ir_should_inline(irb->exec, scope)); |
| 3281 | | ir_mark_gen(ir_build_cond_br(irb, scope, node, is_non_null, continue_block, return_block, is_comptime)); |
| 3282 | | |
| 3283 | | ir_set_cursor_at_end(irb, return_block); |
| 3284 | | ir_gen_defers_for_block(irb, scope, outer_scope, false, true); |
| 3285 | | IrInstruction *null = ir_build_const_null(irb, scope, node); |
| 3286 | | ir_build_return(irb, scope, node, null); |
| 3287 | | |
| 3288 | | ir_set_cursor_at_end(irb, continue_block); |
| 3289 | | IrInstruction *unwrapped_ptr = ir_build_unwrap_maybe(irb, scope, node, maybe_val_ptr, false); |
| 3290 | | if (lval.is_ptr) |
| 3291 | | return unwrapped_ptr; |
| 3292 | | else |
| 3293 | | return ir_build_load_ptr(irb, scope, node, unwrapped_ptr); |
| 3294 | | } |
| 3295 | 3243 | } |
| 3296 | 3244 | zig_unreachable(); |
| 3297 | 3245 | } |
| ... | ... | @@ -3490,7 +3438,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode |
| 3490 | 3438 | return_value = ir_mark_gen(ir_build_const_void(irb, child_scope, block_node)); |
| 3491 | 3439 | } |
| 3492 | 3440 | |
| 3493 | | ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false, false); |
| 3441 | ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); |
| 3494 | 3442 | } |
| 3495 | 3443 | |
| 3496 | 3444 | assert(return_value != nullptr); |
| ... | ... | @@ -5420,7 +5368,7 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *scope, AstNode *node) |
| 5420 | 5368 | } |
| 5421 | 5369 | |
| 5422 | 5370 | IrBasicBlock *dest_block = loop_stack_item->break_block; |
| 5423 | | ir_gen_defers_for_block(irb, scope, dest_block->scope, false, false); |
| 5371 | ir_gen_defers_for_block(irb, scope, dest_block->scope, false); |
| 5424 | 5372 | return ir_build_br(irb, scope, node, dest_block, is_comptime); |
| 5425 | 5373 | } |
| 5426 | 5374 | |
| ... | ... | @@ -5443,7 +5391,7 @@ static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *scope, AstNode *nod |
| 5443 | 5391 | } |
| 5444 | 5392 | |
| 5445 | 5393 | IrBasicBlock *dest_block = loop_stack_item->continue_block; |
| 5446 | | ir_gen_defers_for_block(irb, scope, dest_block->scope, false, false); |
| 5394 | ir_gen_defers_for_block(irb, scope, dest_block->scope, false); |
| 5447 | 5395 | return ir_build_br(irb, scope, node, dest_block, is_comptime); |
| 5448 | 5396 | } |
| 5449 | 5397 | |
| ... | ... | @@ -5784,7 +5732,7 @@ static bool ir_goto_pass2(IrBuilder *irb) { |
| 5784 | 5732 | |
| 5785 | 5733 | IrInstruction *is_comptime = ir_build_const_bool(irb, goto_item->scope, source_node, |
| 5786 | 5734 | ir_should_inline(irb->exec, goto_item->scope) || source_node->data.goto_expr.is_inline); |
| 5787 | | if (!ir_gen_defers_for_block(irb, goto_item->scope, label->bb->scope, false, false)) { |
| 5735 | if (!ir_gen_defers_for_block(irb, goto_item->scope, label->bb->scope, false)) { |
| 5788 | 5736 | add_node_error(irb->codegen, source_node, |
| 5789 | 5737 | buf_sprintf("no label in scope named '%s'", buf_ptr(label_name))); |
| 5790 | 5738 | return false; |