| ... | @@ -237,7 +237,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val) | ... | @@ -237,7 +237,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val) |
| 237 | static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, | 237 | static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, |
| 238 | ZigValue *out_val, ZigValue *ptr_val); | 238 | ZigValue *out_val, ZigValue *ptr_val); |
| 239 | static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *ptr, | 239 | static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *ptr, |
| 240 | IrInst *ptr_src, ZigType *dest_type, IrInst *dest_type_src, bool safety_check_on); | 240 | IrInst *ptr_src, ZigType *dest_type, IrInst *dest_type_src, bool safety_check_on, |
| | 241 | bool keep_bigger_alignment); |
| 241 | static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstGen *value, UndefAllowed undef_allowed); | 242 | static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstGen *value, UndefAllowed undef_allowed); |
| 242 | static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align); | 243 | static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align); |
| 243 | static IrInstGen *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, | 244 | static IrInstGen *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInst* source_instr, IrInstGen *target, |
| ... | @@ -15066,7 +15067,8 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr, | ... | @@ -15066,7 +15067,8 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr, |
| 15066 | dest_ptr_type = wanted_type->data.maybe.child_type; | 15067 | dest_ptr_type = wanted_type->data.maybe.child_type; |
| 15067 | } | 15068 | } |
| 15068 | if (dest_ptr_type != nullptr) { | 15069 | if (dest_ptr_type != nullptr) { |
| 15069 | return ir_analyze_ptr_cast(ira, source_instr, value, source_instr, wanted_type, source_instr, true); | 15070 | return ir_analyze_ptr_cast(ira, source_instr, value, source_instr, wanted_type, source_instr, true, |
| | 15071 | false); |
| 15070 | } | 15072 | } |
| 15071 | } | 15073 | } |
| 15072 | | 15074 | |
| ... | @@ -15108,7 +15110,7 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr, | ... | @@ -15108,7 +15110,7 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr, |
| 15108 | actual_type->data.pointer.child_type, source_node, | 15110 | actual_type->data.pointer.child_type, source_node, |
| 15109 | !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) | 15111 | !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) |
| 15110 | { | 15112 | { |
| 15111 | return ir_analyze_ptr_cast(ira, source_instr, value, source_instr, wanted_type, source_instr, true); | 15113 | return ir_analyze_ptr_cast(ira, source_instr, value, source_instr, wanted_type, source_instr, true, false); |
| 15112 | } | 15114 | } |
| 15113 | | 15115 | |
| 15114 | // cast from integer to C pointer | 15116 | // cast from integer to C pointer |
| ... | @@ -18576,7 +18578,7 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i | ... | @@ -18576,7 +18578,7 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i |
| 18576 | | 18578 | |
| 18577 | result_loc->written = true; | 18579 | result_loc->written = true; |
| 18578 | result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, | 18580 | result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, |
| 18579 | &parent_result_loc->base, ptr_type, &result_cast->base.source_instruction->base, false); | 18581 | &parent_result_loc->base, ptr_type, &result_cast->base.source_instruction->base, false, false); |
| 18580 | return result_loc->resolved_loc; | 18582 | return result_loc->resolved_loc; |
| 18581 | } | 18583 | } |
| 18582 | case ResultLocIdBitCast: { | 18584 | case ResultLocIdBitCast: { |
| ... | @@ -18670,7 +18672,7 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i | ... | @@ -18670,7 +18672,7 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i |
| 18670 | | 18672 | |
| 18671 | result_loc->written = true; | 18673 | result_loc->written = true; |
| 18672 | result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, | 18674 | result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc, |
| 18673 | &parent_result_loc->base, ptr_type, &result_bit_cast->base.source_instruction->base, false); | 18675 | &parent_result_loc->base, ptr_type, &result_bit_cast->base.source_instruction->base, false, false); |
| 18674 | return result_loc->resolved_loc; | 18676 | return result_loc->resolved_loc; |
| 18675 | } | 18677 | } |
| 18676 | } | 18678 | } |
| ... | @@ -22947,7 +22949,7 @@ static IrInstGen *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstSrcSwi | ... | @@ -22947,7 +22949,7 @@ static IrInstGen *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstSrcSwi |
| 22947 | ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes, | 22949 | ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes, |
| 22948 | ref_type->data.pointer.allow_zero); | 22950 | ref_type->data.pointer.allow_zero); |
| 22949 | return ir_analyze_ptr_cast(ira, &instruction->base.base, target_value_ptr, | 22951 | return ir_analyze_ptr_cast(ira, &instruction->base.base, target_value_ptr, |
| 22950 | &instruction->target_value_ptr->base, new_target_value_ptr_type, &instruction->base.base, false); | 22952 | &instruction->target_value_ptr->base, new_target_value_ptr_type, &instruction->base.base, false, false); |
| 22951 | } else { | 22953 | } else { |
| 22952 | ir_add_error(ira, &instruction->base.base, | 22954 | ir_add_error(ira, &instruction->base.base, |
| 22953 | buf_sprintf("switch on type '%s' provides no expression parameter", buf_ptr(&target_type->name))); | 22955 | buf_sprintf("switch on type '%s' provides no expression parameter", buf_ptr(&target_type->name))); |
| ... | @@ -23030,7 +23032,7 @@ static IrInstGen *ir_analyze_instruction_switch_else_var(IrAnalyze *ira, | ... | @@ -23030,7 +23032,7 @@ static IrInstGen *ir_analyze_instruction_switch_else_var(IrAnalyze *ira, |
| 23030 | ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes, | 23032 | ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes, |
| 23031 | ref_type->data.pointer.allow_zero); | 23033 | ref_type->data.pointer.allow_zero); |
| 23032 | return ir_analyze_ptr_cast(ira, &instruction->base.base, target_value_ptr, | 23034 | return ir_analyze_ptr_cast(ira, &instruction->base.base, target_value_ptr, |
| 23033 | &instruction->target_value_ptr->base, new_target_value_ptr_type, &instruction->base.base, false); | 23035 | &instruction->target_value_ptr->base, new_target_value_ptr_type, &instruction->base.base, false, false); |
| 23034 | } | 23036 | } |
| 23035 | | 23037 | |
| 23036 | return target_value_ptr; | 23038 | return target_value_ptr; |
| ... | @@ -27814,7 +27816,8 @@ static IrInstGen *ir_align_cast(IrAnalyze *ira, IrInstGen *target, uint32_t alig | ... | @@ -27814,7 +27816,8 @@ static IrInstGen *ir_align_cast(IrAnalyze *ira, IrInstGen *target, uint32_t alig |
| 27814 | } | 27816 | } |
| 27815 | | 27817 | |
| 27816 | static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *ptr, | 27818 | static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrInstGen *ptr, |
| 27817 | IrInst *ptr_src, ZigType *dest_type, IrInst *dest_type_src, bool safety_check_on) | 27819 | IrInst *ptr_src, ZigType *dest_type, IrInst *dest_type_src, bool safety_check_on, |
| | 27820 | bool keep_bigger_alignment) |
| 27818 | { | 27821 | { |
| 27819 | Error err; | 27822 | Error err; |
| 27820 | | 27823 | |
| ... | @@ -27853,14 +27856,16 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn | ... | @@ -27853,14 +27856,16 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn |
| 27853 | ir_add_error(ira, source_instr, buf_sprintf("cast discards const qualifier")); | 27856 | ir_add_error(ira, source_instr, buf_sprintf("cast discards const qualifier")); |
| 27854 | return ira->codegen->invalid_inst_gen; | 27857 | return ira->codegen->invalid_inst_gen; |
| 27855 | } | 27858 | } |
| 27856 | uint32_t src_align_bytes; | | |
| 27857 | if ((err = resolve_ptr_align(ira, src_type, &src_align_bytes))) | | |
| 27858 | return ira->codegen->invalid_inst_gen; | | |
| 27859 | | | |
| 27860 | uint32_t dest_align_bytes; | 27859 | uint32_t dest_align_bytes; |
| 27861 | if ((err = resolve_ptr_align(ira, dest_type, &dest_align_bytes))) | 27860 | if ((err = resolve_ptr_align(ira, dest_type, &dest_align_bytes))) |
| 27862 | return ira->codegen->invalid_inst_gen; | 27861 | return ira->codegen->invalid_inst_gen; |
| 27863 | | 27862 | |
| | 27863 | uint32_t src_align_bytes = 0; |
| | 27864 | if (keep_bigger_alignment || dest_align_bytes != 1) { |
| | 27865 | if ((err = resolve_ptr_align(ira, src_type, &src_align_bytes))) |
| | 27866 | return ira->codegen->invalid_inst_gen; |
| | 27867 | } |
| | 27868 | |
| 27864 | if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) | 27869 | if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) |
| 27865 | return ira->codegen->invalid_inst_gen; | 27870 | return ira->codegen->invalid_inst_gen; |
| 27866 | | 27871 | |
| ... | @@ -27935,16 +27940,15 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn | ... | @@ -27935,16 +27940,15 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn |
| 27935 | } | 27940 | } |
| 27936 | result->value->type = dest_type; | 27941 | result->value->type = dest_type; |
| 27937 | | 27942 | |
| 27938 | // Keep the bigger alignment, it can only help- | 27943 | // Keep the bigger alignment, it can only help- unless the target is zero bits. |
| 27939 | // unless the target is zero bits. | 27944 | if (keep_bigger_alignment && src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) { |
| 27940 | if (src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) { | | |
| 27941 | result = ir_align_cast(ira, result, src_align_bytes, false); | 27945 | result = ir_align_cast(ira, result, src_align_bytes, false); |
| 27942 | } | 27946 | } |
| 27943 | | 27947 | |
| 27944 | return result; | 27948 | return result; |
| 27945 | } | 27949 | } |
| 27946 | | 27950 | |
| 27947 | if (dest_align_bytes > src_align_bytes) { | 27951 | if (src_align_bytes != 0 && dest_align_bytes > src_align_bytes) { |
| 27948 | ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); | 27952 | ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); |
| 27949 | add_error_note(ira->codegen, msg, ptr_src->source_node, | 27953 | add_error_note(ira->codegen, msg, ptr_src->source_node, |
| 27950 | buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&src_type->name), src_align_bytes)); | 27954 | buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&src_type->name), src_align_bytes)); |
| ... | @@ -27955,10 +27959,9 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn | ... | @@ -27955,10 +27959,9 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn |
| 27955 | | 27959 | |
| 27956 | IrInstGen *casted_ptr = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); | 27960 | IrInstGen *casted_ptr = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on); |
| 27957 | | 27961 | |
| 27958 | // Keep the bigger alignment, it can only help- | 27962 | // Keep the bigger alignment, it can only help- unless the target is zero bits. |
| 27959 | // unless the target is zero bits. | | |
| 27960 | IrInstGen *result; | 27963 | IrInstGen *result; |
| 27961 | if (src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) { | 27964 | if (keep_bigger_alignment && src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) { |
| 27962 | result = ir_align_cast(ira, casted_ptr, src_align_bytes, false); | 27965 | result = ir_align_cast(ira, casted_ptr, src_align_bytes, false); |
| 27963 | if (type_is_invalid(result->value->type)) | 27966 | if (type_is_invalid(result->value->type)) |
| 27964 | return ira->codegen->invalid_inst_gen; | 27967 | return ira->codegen->invalid_inst_gen; |
| ... | @@ -27979,8 +27982,9 @@ static IrInstGen *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstSrcPtrCa | ... | @@ -27979,8 +27982,9 @@ static IrInstGen *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstSrcPtrCa |
| 27979 | if (type_is_invalid(src_type)) | 27982 | if (type_is_invalid(src_type)) |
| 27980 | return ira->codegen->invalid_inst_gen; | 27983 | return ira->codegen->invalid_inst_gen; |
| 27981 | | 27984 | |
| | 27985 | bool keep_bigger_alignment = true; |
| 27982 | return ir_analyze_ptr_cast(ira, &instruction->base.base, ptr, &instruction->ptr->base, | 27986 | return ir_analyze_ptr_cast(ira, &instruction->base.base, ptr, &instruction->ptr->base, |
| 27983 | dest_type, &dest_type_value->base, instruction->safety_check_on); | 27987 | dest_type, &dest_type_value->base, instruction->safety_check_on, keep_bigger_alignment); |
| 27984 | } | 27988 | } |
| 27985 | | 27989 | |
| 27986 | static void buf_write_value_bytes_array(CodeGen *codegen, uint8_t *buf, ZigValue *val, size_t len) { | 27990 | static void buf_write_value_bytes_array(CodeGen *codegen, uint8_t *buf, ZigValue *val, size_t len) { |