| ... | ... | @@ -1399,17 +1399,23 @@ static IrInstruction *ir_build_array_len(IrBuilder *irb, Scope *scope, AstNode * |
| 1399 | 1399 | return &instruction->base; |
| 1400 | 1400 | } |
| 1401 | 1401 | |
| 1402 | | static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { |
| 1402 | static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value, |
| 1403 | bool is_const) |
| 1404 | { |
| 1403 | 1405 | IrInstructionRef *instruction = ir_build_instruction<IrInstructionRef>(irb, scope, source_node); |
| 1404 | 1406 | instruction->value = value; |
| 1407 | instruction->is_const = is_const; |
| 1405 | 1408 | |
| 1406 | 1409 | ir_ref_instruction(value); |
| 1407 | 1410 | |
| 1408 | 1411 | return &instruction->base; |
| 1409 | 1412 | } |
| 1410 | 1413 | |
| 1411 | | static IrInstruction *ir_build_ref_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *value) { |
| 1412 | | IrInstruction *new_instruction = ir_build_ref(irb, old_instruction->scope, old_instruction->source_node, value); |
| 1414 | static IrInstruction *ir_build_ref_from(IrBuilder *irb, IrInstruction *old_instruction, IrInstruction *value, |
| 1415 | bool is_const) |
| 1416 | { |
| 1417 | IrInstruction *new_instruction = ir_build_ref(irb, old_instruction->scope, old_instruction->source_node, |
| 1418 | value, is_const); |
| 1413 | 1419 | ir_link_new_instruction(new_instruction, old_instruction); |
| 1414 | 1420 | return new_instruction; |
| 1415 | 1421 | } |
| ... | ... | @@ -2479,7 +2485,7 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld |
| 2479 | 2485 | assert(fn_entry->type_entry); |
| 2480 | 2486 | IrInstruction *ref_instruction = ir_build_const_fn(irb, scope, source_node, fn_entry); |
| 2481 | 2487 | if (lval != LValPurposeNone) |
| 2482 | | return ir_build_ref(irb, scope, source_node, ref_instruction); |
| 2488 | return ir_build_ref(irb, scope, source_node, ref_instruction, true); |
| 2483 | 2489 | else |
| 2484 | 2490 | return ref_instruction; |
| 2485 | 2491 | } |
| ... | ... | @@ -2489,7 +2495,7 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld |
| 2489 | 2495 | TypeTableEntry *typedef_type = tld_typedef->type_entry; |
| 2490 | 2496 | IrInstruction *ref_instruction = ir_build_const_type(irb, scope, source_node, typedef_type); |
| 2491 | 2497 | if (lval != LValPurposeNone) |
| 2492 | | return ir_build_ref(irb, scope, source_node, ref_instruction); |
| 2498 | return ir_build_ref(irb, scope, source_node, ref_instruction, true); |
| 2493 | 2499 | else |
| 2494 | 2500 | return ref_instruction; |
| 2495 | 2501 | } |
| ... | ... | @@ -2506,7 +2512,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, |
| 2506 | 2512 | if (primitive_table_entry) { |
| 2507 | 2513 | IrInstruction *value = ir_build_const_type(irb, scope, node, primitive_table_entry->value); |
| 2508 | 2514 | if (lval != LValPurposeNone) { |
| 2509 | | return ir_build_ref(irb, scope, node, value); |
| 2515 | return ir_build_ref(irb, scope, node, value, lval == LValPurposeAddressOfConst); |
| 2510 | 2516 | } else { |
| 2511 | 2517 | return value; |
| 2512 | 2518 | } |
| ... | ... | @@ -3105,14 +3111,15 @@ static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction * |
| 3105 | 3111 | |
| 3106 | 3112 | // We needed a pointer to a value, but we got a value. So we create |
| 3107 | 3113 | // an instruction which just makes a const pointer of it. |
| 3108 | | return ir_build_ref(irb, scope, value->source_node, value); |
| 3114 | return ir_build_ref(irb, scope, value->source_node, value, true); |
| 3109 | 3115 | } |
| 3110 | 3116 | |
| 3111 | 3117 | static IrInstruction *ir_gen_address_of(IrBuilder *irb, Scope *scope, AstNode *node, bool is_const, LValPurpose lval) { |
| 3112 | 3118 | assert(node->type == NodeTypePrefixOpExpr); |
| 3113 | 3119 | AstNode *expr_node = node->data.prefix_op_expr.primary_expr; |
| 3114 | 3120 | |
| 3115 | | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, LValPurposeAddressOf); |
| 3121 | IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, |
| 3122 | is_const ? LValPurposeAddressOfConst : LValPurposeAddressOf); |
| 3116 | 3123 | if (value == irb->codegen->invalid_instruction) |
| 3117 | 3124 | return value; |
| 3118 | 3125 | |
| ... | ... | @@ -5102,7 +5109,8 @@ static IrInstruction *ir_analyze_cast_ref(IrAnalyze *ira, IrInstruction *source_ |
| 5102 | 5109 | IrInstructionLoadPtr *load_ptr_inst = (IrInstructionLoadPtr *)value; |
| 5103 | 5110 | return load_ptr_inst->ptr; |
| 5104 | 5111 | } else { |
| 5105 | | IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instr->scope, source_instr->source_node, value); |
| 5112 | IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instr->scope, |
| 5113 | source_instr->source_node, value, true); |
| 5106 | 5114 | |
| 5107 | 5115 | TypeTableEntry *child_type = wanted_type->data.pointer.child_type; |
| 5108 | 5116 | if (type_has_bits(child_type)) { |
| ... | ... | @@ -5454,7 +5462,9 @@ static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruc |
| 5454 | 5462 | } |
| 5455 | 5463 | } |
| 5456 | 5464 | |
| 5457 | | static TypeTableEntry *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *value) { |
| 5465 | static TypeTableEntry *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *value, |
| 5466 | bool is_const) |
| 5467 | { |
| 5458 | 5468 | if (value->type_entry->id == TypeTableEntryIdInvalid) |
| 5459 | 5469 | return ira->codegen->builtin_types.entry_invalid; |
| 5460 | 5470 | |
| ... | ... | @@ -5462,15 +5472,14 @@ static TypeTableEntry *ir_analyze_ref(IrAnalyze *ira, IrInstruction *source_inst |
| 5462 | 5472 | ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); |
| 5463 | 5473 | if (!val) |
| 5464 | 5474 | return ira->codegen->builtin_types.entry_invalid; |
| 5465 | | bool ptr_is_const = false; |
| 5466 | 5475 | return ir_analyze_const_ptr(ira, source_instruction, val, value->type_entry, |
| 5467 | | false, ConstPtrSpecialNone, ptr_is_const); |
| 5476 | false, ConstPtrSpecialNone, is_const); |
| 5468 | 5477 | } |
| 5469 | 5478 | |
| 5470 | 5479 | TypeTableEntry *ptr_type = get_pointer_to_type(ira->codegen, value->type_entry, true); |
| 5471 | 5480 | FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec); |
| 5472 | 5481 | assert(fn_entry); |
| 5473 | | IrInstruction *new_instruction = ir_build_ref_from(&ira->new_irb, source_instruction, value); |
| 5482 | IrInstruction *new_instruction = ir_build_ref_from(&ira->new_irb, source_instruction, value, is_const); |
| 5474 | 5483 | fn_entry->alloca_list.append(new_instruction); |
| 5475 | 5484 | return ptr_type; |
| 5476 | 5485 | } |
| ... | ... | @@ -6986,7 +6995,7 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc |
| 6986 | 6995 | return ir_analyze_const_ptr(ira, instruction, mem_slot, var->type, false, ptr_special, var->src_is_const); |
| 6987 | 6996 | } else { |
| 6988 | 6997 | ir_build_var_ptr_from(&ira->new_irb, instruction, var); |
| 6989 | | return get_pointer_to_type(ira->codegen, var->type, false); |
| 6998 | return get_pointer_to_type(ira->codegen, var->type, var->src_is_const); |
| 6990 | 6999 | } |
| 6991 | 7000 | } |
| 6992 | 7001 | |
| ... | ... | @@ -7130,7 +7139,7 @@ static TypeTableEntry *ir_analyze_container_member_access_inner(IrAnalyze *ira, |
| 7130 | 7139 | bool depends_on_compile_var = container_ptr->static_value.depends_on_compile_var; |
| 7131 | 7140 | IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, field_ptr_instruction->base.scope, |
| 7132 | 7141 | field_ptr_instruction->base.source_node, fn_entry, container_ptr, depends_on_compile_var); |
| 7133 | | return ir_analyze_ref(ira, &field_ptr_instruction->base, bound_fn_value); |
| 7142 | return ir_analyze_ref(ira, &field_ptr_instruction->base, bound_fn_value, true); |
| 7134 | 7143 | } |
| 7135 | 7144 | } |
| 7136 | 7145 | ir_add_error_node(ira, field_ptr_instruction->base.source_node, |
| ... | ... | @@ -8413,7 +8422,7 @@ static TypeTableEntry *ir_analyze_instruction_array_len(IrAnalyze *ira, |
| 8413 | 8422 | |
| 8414 | 8423 | static TypeTableEntry *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRef *ref_instruction) { |
| 8415 | 8424 | IrInstruction *value = ref_instruction->value->other; |
| 8416 | | return ir_analyze_ref(ira, &ref_instruction->base, value); |
| 8425 | return ir_analyze_ref(ira, &ref_instruction->base, value, ref_instruction->is_const); |
| 8417 | 8426 | } |
| 8418 | 8427 | |
| 8419 | 8428 | static TypeTableEntry *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction, |