From 9640b493191e2ec0ff1338751a053a5ef559728d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 17 Sep 2022 10:42:54 +0100 Subject: [PATCH] Fix #1435 type switch statements of empty union types --- src/llvm_backend_stmt.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index a080fc09d..bd622d411 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -1273,6 +1273,7 @@ void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss) { lbValue parent = lb_build_expr(p, as->rhs[0]); bool is_parent_ptr = is_type_pointer(parent.type); + Type *parent_base_type = type_deref(parent.type); TypeSwitchKind switch_kind = check_valid_type_switch_type(parent.type); GB_ASSERT(switch_kind != TypeSwitch_Invalid); @@ -1288,8 +1289,11 @@ void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss) { lbValue union_data = {}; if (switch_kind == TypeSwitch_Union) { union_data = lb_emit_conv(p, parent_ptr, t_rawptr); - if (is_type_union_maybe_pointer(type_deref(parent_ptr.type))) { + Type *union_type = type_deref(parent_ptr.type); + if (is_type_union_maybe_pointer(union_type)) { tag = lb_emit_conv(p, lb_emit_comp_against_nil(p, Token_NotEq, union_data), t_int); + } else if (union_tag_size(union_type) == 0) { + tag = {}; // there is no tag for a zero sized union } else { lbValue tag_ptr = lb_emit_union_tag_ptr(p, parent_ptr); tag = lb_emit_load(p, tag_ptr); @@ -1318,8 +1322,15 @@ void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss) { } } - GB_ASSERT(tag.value != nullptr); - LLVMValueRef switch_instr = LLVMBuildSwitch(p->builder, tag.value, else_block->block, cast(unsigned)num_cases); + + LLVMValueRef switch_instr = nullptr; + if (type_size_of(parent_base_type) == 0) { + GB_ASSERT(tag.value == nullptr); + switch_instr = LLVMBuildSwitch(p->builder, lb_const_bool(p->module, t_llvm_bool, false).value, else_block->block, cast(unsigned)num_cases); + } else { + GB_ASSERT(tag.value != nullptr); + switch_instr = LLVMBuildSwitch(p->builder, tag.value, else_block->block, cast(unsigned)num_cases); + } for_array(i, body->stmts) { Ast *clause = body->stmts[i];