authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-02 16:09:40-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-02 16:09:40-04:00
logd105769926fd5360a5309be3e202cc65d32ce604
tree3b1b518ebad8684cfa4f1a9f6f4f5a65830ecbcf
parent9069ee957cb8c9069028b325af5b862bbf8f66af
signaturelock-open Commit is signed but in an unrecognized format.

fix regressions regarding writing through const pointers


3 files changed, 28 insertions(+), 24 deletions(-)

src/all_types.hpp+2
...@@ -2543,6 +2543,7 @@ struct IrInstructionLoadPtrGen {...@@ -2543,6 +2543,7 @@ struct IrInstructionLoadPtrGen {
2543struct IrInstructionStorePtr {2543struct IrInstructionStorePtr {
2544 IrInstruction base;2544 IrInstruction base;
25452545
2546 bool allow_write_through_const;
2546 IrInstruction *ptr;2547 IrInstruction *ptr;
2547 IrInstruction *value;2548 IrInstruction *value;
2548};2549};
...@@ -3707,6 +3708,7 @@ enum ResultLocId {...@@ -3707,6 +3708,7 @@ enum ResultLocId {
3707struct ResultLoc {3708struct ResultLoc {
3708 ResultLocId id;3709 ResultLocId id;
3709 bool written;3710 bool written;
3711 bool allow_write_through_const;
3710 IrInstruction *resolved_loc; // result ptr 3712 IrInstruction *resolved_loc; // result ptr
3711 IrInstruction *source_instruction;3713 IrInstruction *source_instruction;
3712 IrInstruction *gen_instruction; // value to store to the result loc3714 IrInstruction *gen_instruction; // value to store to the result loc
src/ir.cpp+18-16
...@@ -198,7 +198,7 @@ static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruct...@@ -198,7 +198,7 @@ static IrInstruction *ir_analyze_unwrap_error_payload(IrAnalyze *ira, IrInstruct
198static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr,198static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction *source_instr,
199 IrInstruction *base_ptr, bool initializing);199 IrInstruction *base_ptr, bool initializing);
200static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr,200static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr,
201 IrInstruction *ptr, IrInstruction *uncasted_value);201 IrInstruction *ptr, IrInstruction *uncasted_value, bool allow_write_through_const);
202static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node,202static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node,
203 IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node,203 IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node,
204 LVal lval, ResultLoc *parent_result_loc);204 LVal lval, ResultLoc *parent_result_loc);
...@@ -1613,7 +1613,7 @@ static IrInstruction *ir_build_unreachable(IrBuilder *irb, Scope *scope, AstNode...@@ -1613,7 +1613,7 @@ static IrInstruction *ir_build_unreachable(IrBuilder *irb, Scope *scope, AstNode
1613 return &unreachable_instruction->base;1613 return &unreachable_instruction->base;
1614}1614}
16151615
1616static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,1616static IrInstructionStorePtr *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
1617 IrInstruction *ptr, IrInstruction *value)1617 IrInstruction *ptr, IrInstruction *value)
1618{1618{
1619 IrInstructionStorePtr *instruction = ir_build_instruction<IrInstructionStorePtr>(irb, scope, source_node);1619 IrInstructionStorePtr *instruction = ir_build_instruction<IrInstructionStorePtr>(irb, scope, source_node);
...@@ -1625,7 +1625,7 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *...@@ -1625,7 +1625,7 @@ static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *
1625 ir_ref_instruction(ptr, irb->current_basic_block);1625 ir_ref_instruction(ptr, irb->current_basic_block);
1626 ir_ref_instruction(value, irb->current_basic_block);1626 ir_ref_instruction(value, irb->current_basic_block);
16271627
1628 return &instruction->base;1628 return instruction;
1629}1629}
16301630
1631static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNode *source_node,1631static IrInstruction *ir_build_var_decl_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
...@@ -6051,6 +6051,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A...@@ -6051,6 +6051,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A
6051 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1);6051 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1);
6052 result_loc_inst->base.id = ResultLocIdInstruction;6052 result_loc_inst->base.id = ResultLocIdInstruction;
6053 result_loc_inst->base.source_instruction = field_ptr;6053 result_loc_inst->base.source_instruction = field_ptr;
6054 result_loc_inst->base.allow_write_through_const = true;
6054 ir_ref_instruction(field_ptr, irb->current_basic_block);6055 ir_ref_instruction(field_ptr, irb->current_basic_block);
6055 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base);6056 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base);
60566057
...@@ -6089,6 +6090,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A...@@ -6089,6 +6090,7 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A
6089 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1);6090 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1);
6090 result_loc_inst->base.id = ResultLocIdInstruction;6091 result_loc_inst->base.id = ResultLocIdInstruction;
6091 result_loc_inst->base.source_instruction = elem_ptr;6092 result_loc_inst->base.source_instruction = elem_ptr;
6093 result_loc_inst->base.allow_write_through_const = true;
6092 ir_ref_instruction(elem_ptr, irb->current_basic_block);6094 ir_ref_instruction(elem_ptr, irb->current_basic_block);
6093 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base);6095 ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base);
60946096
...@@ -6646,7 +6648,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo...@@ -6646,7 +6648,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
66466648
6647 ir_set_cursor_at_end_and_append_block(irb, continue_block);6649 ir_set_cursor_at_end_and_append_block(irb, continue_block);
6648 IrInstruction *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false);6650 IrInstruction *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false);
6649 ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val));6651 ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val)->allow_write_through_const = true;
6650 ir_build_br(irb, child_scope, node, cond_block, is_comptime);6652 ir_build_br(irb, child_scope, node, cond_block, is_comptime);
66516653
6652 IrInstruction *else_result = nullptr;6654 IrInstruction *else_result = nullptr;
...@@ -14848,7 +14850,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,...@@ -14848,7 +14850,7 @@ static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira,
14848 // instruction.14850 // instruction.
14849 assert(deref->value.special != ConstValSpecialRuntime);14851 assert(deref->value.special != ConstValSpecialRuntime);
14850 var_ptr->value.special = ConstValSpecialRuntime;14852 var_ptr->value.special = ConstValSpecialRuntime;
14851 ir_analyze_store_ptr(ira, var_ptr, var_ptr, deref);14853 ir_analyze_store_ptr(ira, var_ptr, var_ptr, deref, false);
14852 }14854 }
1485314855
14854 if (var_ptr->value.special == ConstValSpecialStatic && var->mem_slot_index != SIZE_MAX) {14856 if (var_ptr->value.special == ConstValSpecialStatic && var->mem_slot_index != SIZE_MAX) {
...@@ -15862,7 +15864,7 @@ no_mem_slot:...@@ -15862,7 +15864,7 @@ no_mem_slot:
15862}15864}
1586315865
15864static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr,15866static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr,
15865 IrInstruction *ptr, IrInstruction *uncasted_value)15867 IrInstruction *ptr, IrInstruction *uncasted_value, bool allow_write_through_const)
15866{15868{
15867 assert(ptr->value.type->id == ZigTypeIdPointer);15869 assert(ptr->value.type->id == ZigTypeIdPointer);
1586815870
...@@ -15878,7 +15880,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source...@@ -15878,7 +15880,7 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
1587815880
15879 ZigType *child_type = ptr->value.type->data.pointer.child_type;15881 ZigType *child_type = ptr->value.type->data.pointer.child_type;
1588015882
15881 if (ptr->value.type->data.pointer.is_const && !source_instr->is_gen) {15883 if (ptr->value.type->data.pointer.is_const && !allow_write_through_const) {
15882 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));15884 ir_add_error(ira, source_instr, buf_sprintf("cannot assign to constant"));
15883 return ira->codegen->invalid_instruction;15885 return ira->codegen->invalid_instruction;
15884 }15886 }
...@@ -15957,10 +15959,9 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source...@@ -15957,10 +15959,9 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
15957 break;15959 break;
15958 }15960 }
1595915961
15960 IrInstruction *result = ir_build_store_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node,15962 IrInstructionStorePtr *store_ptr = ir_build_store_ptr(&ira->new_irb, source_instr->scope,
15961 ptr, value);15963 source_instr->source_node, ptr, value);
15962 result->value.type = ira->codegen->builtin_types.entry_void;15964 return &store_ptr->base;
15963 return result;
15964}15965}
1596515966
15966static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction,15967static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction,
...@@ -18283,7 +18284,7 @@ static IrInstruction *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstruc...@@ -18283,7 +18284,7 @@ static IrInstruction *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstruc
18283 if (type_is_invalid(value->value.type))18284 if (type_is_invalid(value->value.type))
18284 return ira->codegen->invalid_instruction;18285 return ira->codegen->invalid_instruction;
1828518286
18286 return ir_analyze_store_ptr(ira, &instruction->base, ptr, value);18287 return ir_analyze_store_ptr(ira, &instruction->base, ptr, value, instruction->allow_write_through_const);
18287}18288}
1828818289
18289static IrInstruction *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstructionLoadPtr *instruction) {18290static IrInstruction *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstructionLoadPtr *instruction) {
...@@ -19691,7 +19692,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc...@@ -19691,7 +19692,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
1969119692
19692 IrInstruction *field_ptr = ir_analyze_struct_field_ptr(ira, instruction, field, result_loc,19693 IrInstruction *field_ptr = ir_analyze_struct_field_ptr(ira, instruction, field, result_loc,
19693 container_type, true);19694 container_type, true);
19694 ir_analyze_store_ptr(ira, instruction, field_ptr, runtime_inst);19695 ir_analyze_store_ptr(ira, instruction, field_ptr, runtime_inst, false);
19695 if (instr_is_comptime(field_ptr) && field_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) {19696 if (instr_is_comptime(field_ptr) && field_ptr->value.data.x_ptr.mut != ConstPtrMutRuntimeVar) {
19696 const_ptrs.append(field_ptr);19697 const_ptrs.append(field_ptr);
19697 } else {19698 } else {
...@@ -19708,7 +19709,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc...@@ -19708,7 +19709,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
19708 IrInstruction *field_result_loc = const_ptrs.at(i);19709 IrInstruction *field_result_loc = const_ptrs.at(i);
19709 IrInstruction *deref = ir_get_deref(ira, field_result_loc, field_result_loc, nullptr);19710 IrInstruction *deref = ir_get_deref(ira, field_result_loc, field_result_loc, nullptr);
19710 field_result_loc->value.special = ConstValSpecialRuntime;19711 field_result_loc->value.special = ConstValSpecialRuntime;
19711 ir_analyze_store_ptr(ira, field_result_loc, field_result_loc, deref);19712 ir_analyze_store_ptr(ira, field_result_loc, field_result_loc, deref, false);
19712 }19713 }
19713 }19714 }
19714 }19715 }
...@@ -19835,7 +19836,7 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,...@@ -19835,7 +19836,7 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
19835 assert(elem_result_loc->value.special == ConstValSpecialStatic);19836 assert(elem_result_loc->value.special == ConstValSpecialStatic);
19836 IrInstruction *deref = ir_get_deref(ira, elem_result_loc, elem_result_loc, nullptr);19837 IrInstruction *deref = ir_get_deref(ira, elem_result_loc, elem_result_loc, nullptr);
19837 elem_result_loc->value.special = ConstValSpecialRuntime;19838 elem_result_loc->value.special = ConstValSpecialRuntime;
19838 ir_analyze_store_ptr(ira, elem_result_loc, elem_result_loc, deref);19839 ir_analyze_store_ptr(ira, elem_result_loc, elem_result_loc, deref, false);
19839 }19840 }
19840 }19841 }
19841 }19842 }
...@@ -25418,7 +25419,8 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct...@@ -25418,7 +25419,8 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct
25418 return result_loc;25419 return result_loc;
2541925420
25420 if (!was_written) {25421 if (!was_written) {
25421 IrInstruction *store_ptr = ir_analyze_store_ptr(ira, &instruction->base, result_loc, value);25422 IrInstruction *store_ptr = ir_analyze_store_ptr(ira, &instruction->base, result_loc, value,
25423 instruction->result_loc->allow_write_through_const);
25422 if (type_is_invalid(store_ptr->value.type)) {25424 if (type_is_invalid(store_ptr->value.type)) {
25423 return ira->codegen->invalid_instruction;25425 return ira->codegen->invalid_instruction;
25424 }25426 }
test/compile_errors.zig+8-8
...@@ -201,7 +201,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -201,7 +201,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
201 \\ return error.OutOfMemory;201 \\ return error.OutOfMemory;
202 \\}202 \\}
203 ,203 ,
204 "tmp.zig:2:7: error: error is discarded",204 "tmp.zig:2:12: error: error is discarded",
205 );205 );
206206
207 cases.add(207 cases.add(
...@@ -2740,7 +2740,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2740,7 +2740,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2740 \\ 3 = 3;2740 \\ 3 = 3;
2741 \\}2741 \\}
2742 ,2742 ,
2743 "tmp.zig:2:7: error: cannot assign to constant",2743 "tmp.zig:2:9: error: cannot assign to constant",
2744 );2744 );
27452745
2746 cases.add(2746 cases.add(
...@@ -2750,7 +2750,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2750,7 +2750,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2750 \\ a = 4;2750 \\ a = 4;
2751 \\}2751 \\}
2752 ,2752 ,
2753 "tmp.zig:3:7: error: cannot assign to constant",2753 "tmp.zig:3:9: error: cannot assign to constant",
2754 );2754 );
27552755
2756 cases.add(2756 cases.add(
...@@ -2820,7 +2820,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2820,7 +2820,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2820 \\}2820 \\}
2821 \\export fn entry() void { f(); }2821 \\export fn entry() void { f(); }
2822 ,2822 ,
2823 "tmp.zig:3:7: error: cannot assign to constant",2823 "tmp.zig:3:9: error: cannot assign to constant",
2824 );2824 );
28252825
2826 cases.add(2826 cases.add(
...@@ -3883,7 +3883,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -3883,7 +3883,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
3883 \\3883 \\
3884 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }3884 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }
3885 ,3885 ,
3886 "tmp.zig:6:24: error: unable to evaluate constant expression",3886 "tmp.zig:6:26: error: unable to evaluate constant expression",
3887 "tmp.zig:4:17: note: called from here",3887 "tmp.zig:4:17: note: called from here",
3888 );3888 );
38893889
...@@ -4133,7 +4133,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4133,7 +4133,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4133 \\ cstr[0] = 'W';4133 \\ cstr[0] = 'W';
4134 \\}4134 \\}
4135 ,4135 ,
4136 "tmp.zig:3:11: error: cannot assign to constant",4136 "tmp.zig:3:13: error: cannot assign to constant",
4137 );4137 );
41384138
4139 cases.add(4139 cases.add(
...@@ -4143,7 +4143,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4143,7 +4143,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4143 \\ cstr[0] = 'W';4143 \\ cstr[0] = 'W';
4144 \\}4144 \\}
4145 ,4145 ,
4146 "tmp.zig:3:11: error: cannot assign to constant",4146 "tmp.zig:3:13: error: cannot assign to constant",
4147 );4147 );
41484148
4149 cases.add(4149 cases.add(
...@@ -4291,7 +4291,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4291,7 +4291,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4291 \\ f.field = 0;4291 \\ f.field = 0;
4292 \\}4292 \\}
4293 ,4293 ,
4294 "tmp.zig:6:13: error: cannot assign to constant",4294 "tmp.zig:6:15: error: cannot assign to constant",
4295 );4295 );
42964296
4297 cases.add(4297 cases.add(