diff options
| author | gingerBill <bill@gingerbill.org> | 2020-03-25 15:55:00 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2020-03-25 15:55:00 +0000 |
| commit | 0a920b5439a66c08dedd4bfbef76223bd8fb8a13 (patch) | |
| tree | e2c262be18be37093e87ca12929dfba9eb32dd2b | |
| parent | 921ee82c974541cdb2be72f9ea9eee82bc44ad3b (diff) | |
Fix map references in selector expressions
| -rw-r--r-- | src/ir.cpp | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index 8feab6419..8a36be1f5 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -3922,7 +3922,7 @@ irValue *ir_addr_load(irProcedure *proc, irAddr const &addr) { return ir_emit_load(proc, addr.addr); } -irValue *ir_addr_get_ptr(irProcedure *proc, irAddr const &addr) { +irValue *ir_addr_get_ptr(irProcedure *proc, irAddr const &addr, bool allow_reference=false) { if (addr.addr == nullptr) { GB_PANIC("Illegal addr -> nullptr"); return nullptr; @@ -3930,16 +3930,21 @@ irValue *ir_addr_get_ptr(irProcedure *proc, irAddr const &addr) { switch (addr.kind) { case irAddr_Map: { - Type *map_type = base_type(addr.map_type); - irValue *h = ir_gen_map_header(proc, addr.addr, map_type); - irValue *key = ir_gen_map_key(proc, addr.map_key, map_type->Map.key); + if (allow_reference) { + Type *map_type = base_type(addr.map_type); + irValue *h = ir_gen_map_header(proc, addr.addr, map_type); + irValue *key = ir_gen_map_key(proc, addr.map_key, map_type->Map.key); - auto args = array_make<irValue *>(ir_allocator(), 2); - args[0] = h; - args[1] = key; + auto args = array_make<irValue *>(ir_allocator(), 2); + args[0] = h; + args[1] = key; - irValue *ptr = ir_emit_runtime_call(proc, "__dynamic_map_get", args); - return ir_emit_conv(proc, ptr, alloc_type_pointer(map_type->Map.value)); + irValue *ptr = ir_emit_runtime_call(proc, "__dynamic_map_get", args); + return ir_emit_conv(proc, ptr, alloc_type_pointer(map_type->Map.value)); + } else { + irValue *v = ir_addr_load(proc, addr); + return ir_address_from_load_or_generate_local(proc, v); + } } @@ -7333,7 +7338,9 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) { #endif } - return ir_build_addr_ptr(proc, ue->expr); + bool allow_reference = true; + irAddr addr = ir_build_addr(proc, ue->expr); + return ir_addr_get_ptr(proc, addr, allow_reference); } default: return ir_emit_unary_arith(proc, ue->op.kind, ir_build_expr(proc, ue->expr), tv.type); @@ -10053,7 +10060,8 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) { is_map = true; gbAllocator a = ir_allocator(); irAddr addr = ir_build_addr(proc, expr); - irValue *map = ir_addr_get_ptr(proc, addr); + bool allow_reference = true; + irValue *map = ir_addr_get_ptr(proc, addr, allow_reference); if (is_type_pointer(ir_addr_type(addr))) { map = ir_addr_load(proc, addr); } |