authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-02-05 20:49:14-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-02-05 20:49:14-05:00
log28f63b8a4f2e55d2596a0e3daea106500a479791
tree4ceb95b0d8a5c8de8cdf00929fbe6ace3d749131
parentd26bb3ae2e9add11ef350e5d7b040dfbe10539be

fix volatile not respected for storing through a struct pointer


2 files changed, 25 insertions(+), 17 deletions(-)

src/all_types.hpp+1
...@@ -1740,6 +1740,7 @@ struct IrInstructionVarPtr {...@@ -1740,6 +1740,7 @@ struct IrInstructionVarPtr {
17401740
1741 VariableTableEntry *var;1741 VariableTableEntry *var;
1742 bool is_const;1742 bool is_const;
1743 bool is_volatile;
1743};1744};
17441745
1745struct IrInstructionCall {1746struct IrInstructionCall {
src/ir.cpp+24-17
...@@ -770,11 +770,12 @@ static IrInstruction *ir_build_bin_op_from(IrBuilder *irb, IrInstruction *old_in...@@ -770,11 +770,12 @@ static IrInstruction *ir_build_bin_op_from(IrBuilder *irb, IrInstruction *old_in
770}770}
771771
772static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,772static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
773 VariableTableEntry *var, bool is_const)773 VariableTableEntry *var, bool is_const, bool is_volatile)
774{774{
775 IrInstructionVarPtr *instruction = ir_build_instruction<IrInstructionVarPtr>(irb, scope, source_node);775 IrInstructionVarPtr *instruction = ir_build_instruction<IrInstructionVarPtr>(irb, scope, source_node);
776 instruction->var = var;776 instruction->var = var;
777 instruction->is_const = is_const;777 instruction->is_const = is_const;
778 instruction->is_volatile = is_volatile;
778779
779 ir_ref_var(var);780 ir_ref_var(var);
780781
...@@ -782,10 +783,10 @@ static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *so...@@ -782,10 +783,10 @@ static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *so
782}783}
783784
784static IrInstruction *ir_build_var_ptr_from(IrBuilder *irb, IrInstruction *old_instruction,785static IrInstruction *ir_build_var_ptr_from(IrBuilder *irb, IrInstruction *old_instruction,
785 VariableTableEntry *var, bool is_const)786 VariableTableEntry *var, bool is_const, bool is_volatile)
786{787{
787 IrInstruction *new_instruction = ir_build_var_ptr(irb, old_instruction->scope,788 IrInstruction *new_instruction = ir_build_var_ptr(irb, old_instruction->scope,
788 old_instruction->source_node, var, is_const);789 old_instruction->source_node, var, is_const, is_volatile);
789 ir_link_new_instruction(new_instruction, old_instruction);790 ir_link_new_instruction(new_instruction, old_instruction);
790 return new_instruction;791 return new_instruction;
791792
...@@ -3599,7 +3600,8 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld...@@ -3599,7 +3600,8 @@ static IrInstruction *ir_gen_decl_ref(IrBuilder *irb, AstNode *source_node, Tld
3599 {3600 {
3600 TldVar *tld_var = (TldVar *)tld;3601 TldVar *tld_var = (TldVar *)tld;
3601 VariableTableEntry *var = tld_var->var;3602 VariableTableEntry *var = tld_var->var;
3602 IrInstruction *var_ptr = ir_build_var_ptr(irb, scope, source_node, var, !lval.is_ptr || lval.is_const);3603 IrInstruction *var_ptr = ir_build_var_ptr(irb, scope, source_node, var,
3604 !lval.is_ptr || lval.is_const, lval.is_ptr && lval.is_volatile);
3603 if (lval.is_ptr)3605 if (lval.is_ptr)
3604 return var_ptr;3606 return var_ptr;
3605 else3607 else
...@@ -3648,7 +3650,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -3648,7 +3650,7 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
3648 VariableTableEntry *var = find_variable(irb->codegen, scope, variable_name);3650 VariableTableEntry *var = find_variable(irb->codegen, scope, variable_name);
3649 if (var) {3651 if (var) {
3650 IrInstruction *var_ptr = ir_build_var_ptr(irb, scope, node, var,3652 IrInstruction *var_ptr = ir_build_var_ptr(irb, scope, node, var,
3651 !lval.is_ptr || lval.is_const);3653 !lval.is_ptr || lval.is_const, lval.is_ptr && lval.is_volatile);
3652 if (lval.is_ptr)3654 if (lval.is_ptr)
3653 return var_ptr;3655 return var_ptr;
3654 else3656 else
...@@ -4584,7 +4586,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo...@@ -4584,7 +4586,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
45844586
4585 IrInstruction *undefined_value = ir_build_const_undefined(irb, child_scope, elem_node);4587 IrInstruction *undefined_value = ir_build_const_undefined(irb, child_scope, elem_node);
4586 ir_build_var_decl(irb, child_scope, elem_node, elem_var, elem_var_type, undefined_value);4588 ir_build_var_decl(irb, child_scope, elem_node, elem_var, elem_var_type, undefined_value);
4587 IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, child_scope, node, elem_var, false);4589 IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, child_scope, node, elem_var, false, false);
45884590
4589 AstNode *index_var_source_node;4591 AstNode *index_var_source_node;
4590 VariableTableEntry *index_var;4592 VariableTableEntry *index_var;
...@@ -4602,7 +4604,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo...@@ -4602,7 +4604,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
4602 IrInstruction *zero = ir_build_const_usize(irb, child_scope, node, 0);4604 IrInstruction *zero = ir_build_const_usize(irb, child_scope, node, 0);
4603 IrInstruction *one = ir_build_const_usize(irb, child_scope, node, 1);4605 IrInstruction *one = ir_build_const_usize(irb, child_scope, node, 1);
4604 ir_build_var_decl(irb, child_scope, index_var_source_node, index_var, usize, zero);4606 ir_build_var_decl(irb, child_scope, index_var_source_node, index_var, usize, zero);
4605 IrInstruction *index_ptr = ir_build_var_ptr(irb, child_scope, node, index_var, false);4607 IrInstruction *index_ptr = ir_build_var_ptr(irb, child_scope, node, index_var, false, false);
46064608
46074609
4608 IrBasicBlock *cond_block = ir_build_basic_block(irb, child_scope, "ForCond");4610 IrBasicBlock *cond_block = ir_build_basic_block(irb, child_scope, "ForCond");
...@@ -8678,7 +8680,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP...@@ -8678,7 +8680,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
8678}8680}
86798681
8680static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruction,8682static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruction,
8681 VariableTableEntry *var, bool is_const_ptr, bool depends_on_compile_var)8683 VariableTableEntry *var, bool is_const_ptr, bool is_volatile_ptr, bool depends_on_compile_var)
8682{8684{
8683 assert(var->value.type);8685 assert(var->value.type);
8684 if (var->value.type->id == TypeTableEntryIdInvalid)8686 if (var->value.type->id == TypeTableEntryIdInvalid)
...@@ -8697,14 +8699,15 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc...@@ -8697,14 +8699,15 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc
8697 mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];8699 mem_slot = &ira->exec_context.mem_slot_list[var->mem_slot_index];
8698 }8700 }
86998701
8702 bool is_const = (var->value.type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const;
8703 bool is_volatile = (var->value.type->id == TypeTableEntryIdMetaType) ? is_volatile_ptr : false;
8700 if (mem_slot && mem_slot->special != ConstValSpecialRuntime) {8704 if (mem_slot && mem_slot->special != ConstValSpecialRuntime) {
8701 ConstPtrSpecial ptr_special = is_comptime ? ConstPtrSpecialInline : ConstPtrSpecialNone;8705 ConstPtrSpecial ptr_special = is_comptime ? ConstPtrSpecialInline : ConstPtrSpecialNone;
8702 bool is_const = (var->value.type->id == TypeTableEntryIdMetaType) ? is_const_ptr : var->src_is_const;
8703 depends_on_compile_var = mem_slot->depends_on_compile_var || depends_on_compile_var || is_comptime;8706 depends_on_compile_var = mem_slot->depends_on_compile_var || depends_on_compile_var || is_comptime;
8704 return ir_analyze_const_ptr(ira, instruction, mem_slot, var->value.type,8707 return ir_analyze_const_ptr(ira, instruction, mem_slot, var->value.type,
8705 depends_on_compile_var, ptr_special, is_const, false);8708 depends_on_compile_var, ptr_special, is_const, is_volatile);
8706 } else {8709 } else {
8707 ir_build_var_ptr_from(&ira->new_irb, instruction, var, false);8710 ir_build_var_ptr_from(&ira->new_irb, instruction, var, is_const, is_volatile);
8708 type_ensure_zero_bits_known(ira->codegen, var->value.type);8711 type_ensure_zero_bits_known(ira->codegen, var->value.type);
8709 return get_pointer_to_type(ira->codegen, var->value.type, var->src_is_const);8712 return get_pointer_to_type(ira->codegen, var->value.type, var->src_is_const);
8710 }8713 }
...@@ -8712,7 +8715,8 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc...@@ -8712,7 +8715,8 @@ static TypeTableEntry *ir_analyze_var_ptr(IrAnalyze *ira, IrInstruction *instruc
87128715
8713static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *var_ptr_instruction) {8716static TypeTableEntry *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *var_ptr_instruction) {
8714 VariableTableEntry *var = var_ptr_instruction->var;8717 VariableTableEntry *var = var_ptr_instruction->var;
8715 return ir_analyze_var_ptr(ira, &var_ptr_instruction->base, var, var_ptr_instruction->is_const, false);8718 return ir_analyze_var_ptr(ira, &var_ptr_instruction->base, var, var_ptr_instruction->is_const,
8719 var_ptr_instruction->is_volatile, false);
8716}8720}
87178721
8718static VariableTableEntry *get_fn_var_by_index(FnTableEntry *fn_entry, size_t index) {8722static VariableTableEntry *get_fn_var_by_index(FnTableEntry *fn_entry, size_t index) {
...@@ -8784,12 +8788,15 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc...@@ -8784,12 +8788,15 @@ static TypeTableEntry *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruc
8784 VariableTableEntry *var = get_fn_var_by_index(fn_entry, abs_index);8788 VariableTableEntry *var = get_fn_var_by_index(fn_entry, abs_index);
8785 bool depends_on_compile_var = array_ptr->value.depends_on_compile_var ||8789 bool depends_on_compile_var = array_ptr->value.depends_on_compile_var ||
8786 elem_index->value.depends_on_compile_var;8790 elem_index->value.depends_on_compile_var;
8791 bool is_const = true;
8792 bool is_volatile = false;
8787 if (var) {8793 if (var) {
8788 return ir_analyze_var_ptr(ira, &elem_ptr_instruction->base, var, true, depends_on_compile_var);8794 return ir_analyze_var_ptr(ira, &elem_ptr_instruction->base, var,
8795 is_const, is_volatile, depends_on_compile_var);
8789 } else {8796 } else {
8790 return ir_analyze_const_ptr(ira, &elem_ptr_instruction->base, &ira->codegen->const_void_val,8797 return ir_analyze_const_ptr(ira, &elem_ptr_instruction->base, &ira->codegen->const_void_val,
8791 ira->codegen->builtin_types.entry_void, depends_on_compile_var, ConstPtrSpecialNone,8798 ira->codegen->builtin_types.entry_void, depends_on_compile_var, ConstPtrSpecialNone,
8792 true, false);8799 is_const, is_volatile);
8793 }8800 }
8794 } else {8801 } else {
8795 ir_add_error_node(ira, elem_ptr_instruction->base.source_node,8802 ir_add_error_node(ira, elem_ptr_instruction->base.source_node,
...@@ -8981,7 +8988,7 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source...@@ -8981,7 +8988,7 @@ static TypeTableEntry *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source
8981 {8988 {
8982 TldVar *tld_var = (TldVar *)tld;8989 TldVar *tld_var = (TldVar *)tld;
8983 VariableTableEntry *var = tld_var->var;8990 VariableTableEntry *var = tld_var->var;
8984 return ir_analyze_var_ptr(ira, source_instruction, var, false, depends_on_compile_var);8991 return ir_analyze_var_ptr(ira, source_instruction, var, false, false, depends_on_compile_var);
8985 }8992 }
8986 case TldIdFn:8993 case TldIdFn:
8987 {8994 {
...@@ -12296,12 +12303,12 @@ FnTableEntry *ir_create_inline_fn(CodeGen *codegen, Buf *fn_name, VariableTableE...@@ -12296,12 +12303,12 @@ FnTableEntry *ir_create_inline_fn(CodeGen *codegen, Buf *fn_name, VariableTableE
12296 // Entry block gets a reference because we enter it to begin.12303 // Entry block gets a reference because we enter it to begin.
12297 ir_ref_bb(irb->current_basic_block);12304 ir_ref_bb(irb->current_basic_block);
1229812305
12299 IrInstruction *maybe_fn_ptr = ir_build_var_ptr(irb, scope, source_node, var, true);12306 IrInstruction *maybe_fn_ptr = ir_build_var_ptr(irb, scope, source_node, var, true, false);
12300 IrInstruction *unwrapped_fn_ptr = ir_build_unwrap_maybe(irb, scope, source_node, maybe_fn_ptr, true);12307 IrInstruction *unwrapped_fn_ptr = ir_build_unwrap_maybe(irb, scope, source_node, maybe_fn_ptr, true);
12301 IrInstruction *fn_ref_instruction = ir_build_load_ptr(irb, scope, source_node, unwrapped_fn_ptr);12308 IrInstruction *fn_ref_instruction = ir_build_load_ptr(irb, scope, source_node, unwrapped_fn_ptr);
1230212309
12303 for (size_t i = 0; i < arg_count; i += 1) {12310 for (size_t i = 0; i < arg_count; i += 1) {
12304 IrInstruction *var_ptr_instruction = ir_build_var_ptr(irb, scope, source_node, arg_vars[i], true);12311 IrInstruction *var_ptr_instruction = ir_build_var_ptr(irb, scope, source_node, arg_vars[i], true, false);
12305 args[i] = ir_build_load_ptr(irb, scope, source_node, var_ptr_instruction);12312 args[i] = ir_build_load_ptr(irb, scope, source_node, var_ptr_instruction);
12306 }12313 }
1230712314