diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-04-13 22:42:36 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-04-13 22:42:36 +0100 |
| commit | 0d2dbee84e937ccf411787f9dda72e541db3fd20 (patch) | |
| tree | a0f8853f682e46161c38273c727896b1f998ade6 /src/ir.c | |
| parent | d8d22e34dd63547cb6492e8e15b55fcaec4cb3e5 (diff) | |
Fix addressing mode rules for `match in` statements
Diffstat (limited to 'src/ir.c')
| -rw-r--r-- | src/ir.c | 13 |
1 files changed, 11 insertions, 2 deletions
@@ -6239,7 +6239,13 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) { ir_start_block(proc, body); if (cc->list.count == 1) { - Type *ct = make_type_pointer(proc->module->allocator, case_entity->type); + bool any_or_not_ptr = is_type_any(type_deref(parent_type)) || !is_parent_ptr; + + Type *ct = case_entity->type; + if (any_or_not_ptr) { + ct = make_type_pointer(proc->module->allocator, ct); + } + GB_ASSERT_MSG(is_type_pointer(ct), "%s", type_to_string(ct)); irValue *data = NULL; if (match_type_kind == MatchType_Union) { data = union_data; @@ -6247,7 +6253,10 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) { irValue *any_data = ir_emit_load(proc, ir_emit_struct_ep(proc, parent_ptr, 1)); data = any_data; } - value = ir_emit_load(proc, ir_emit_conv(proc, data, ct)); + value = ir_emit_conv(proc, data, ct); + if (any_or_not_ptr) { + value = ir_emit_load(proc, value); + } } ir_store_type_case_implicit(proc, clause, value); |