diff options
| author | gingerBill <bill@gingerbill.org> | 2024-05-13 11:57:04 +0100 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2024-05-13 11:57:04 +0100 |
| commit | 3fb0d52a745ba7215201234e18995e7489cc1f24 (patch) | |
| tree | 1762497d4da24ad9049acdbad1676b6ef381ac4c /src/llvm_backend_expr.cpp | |
| parent | 07a538cd82616b3a174bdde4934a4d80ad40fb33 (diff) | |
Fix #3585
Diffstat (limited to 'src/llvm_backend_expr.cpp')
| -rw-r--r-- | src/llvm_backend_expr.cpp | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index ad02ff7dd..4c5ff76bc 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -5194,6 +5194,54 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) { lbValue ptr = lb_address_from_load_or_generate_local(p, lb_build_expr(p, expr)); return lb_addr(ptr); case_end; + + + case_ast_node(be, OrBranchExpr, expr); + lbBlock *block = nullptr; + + if (be->label != nullptr) { + lbBranchBlocks bb = lb_lookup_branch_blocks(p, be->label); + switch (be->token.kind) { + case Token_or_break: block = bb.break_; break; + case Token_or_continue: block = bb.continue_; break; + } + } else { + for (lbTargetList *t = p->target_list; t != nullptr && block == nullptr; t = t->prev) { + if (t->is_block) { + continue; + } + + switch (be->token.kind) { + case Token_or_break: block = t->break_; break; + case Token_or_continue: block = t->continue_; break; + } + } + } + + GB_ASSERT(block != nullptr); + TypeAndValue tv = expr->tav; + + lbValue lhs = {}; + lbValue rhs = {}; + lb_emit_try_lhs_rhs(p, be->expr, tv, &lhs, &rhs); + Type *type = default_type(tv.type); + if (lhs.value) { + lhs = lb_emit_conv(p, lhs, type); + } else if (type != nullptr && type != t_invalid) { + lhs = lb_const_nil(p->module, type); + } + + lbBlock *then = lb_create_block(p, "or_branch.then"); + lbBlock *else_ = lb_create_block(p, "or_branch.else"); + + lb_emit_if(p, lb_emit_try_has_value(p, rhs), then, else_); + lb_start_block(p, else_); + lb_emit_defer_stmts(p, lbDeferExit_Branch, block); + lb_emit_jump(p, block); + lb_start_block(p, then); + + return lb_addr(lb_address_from_load_or_generate_local(p, lhs)); + case_end; } TokenPos token_pos = ast_token(expr).pos; |