| ... | ... | @@ -237,7 +237,8 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val) |
| 237 | 237 | static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, |
| 238 | 238 | ZigValue *out_val, ZigValue *ptr_val); |
| 239 | 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 | 242 | static ZigValue *ir_resolve_const(IrAnalyze *ira, IrInstGen *value, UndefAllowed undef_allowed); |
| 242 | 243 | static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align); |
| 243 | 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 | 15067 | dest_ptr_type = wanted_type->data.maybe.child_type; |
| 15067 | 15068 | } |
| 15068 | 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 | 15110 | actual_type->data.pointer.child_type, source_node, |
| 15109 | 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 | 15116 | // cast from integer to C pointer |
| ... | ... | @@ -18576,7 +18578,7 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i |
| 18576 | 18578 | |
| 18577 | 18579 | result_loc->written = true; |
| 18578 | 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 | 18582 | return result_loc->resolved_loc; |
| 18581 | 18583 | } |
| 18582 | 18584 | case ResultLocIdBitCast: { |
| ... | ... | @@ -18670,7 +18672,7 @@ static IrInstGen *ir_resolve_result_raw(IrAnalyze *ira, IrInst *suspend_source_i |
| 18670 | 18672 | |
| 18671 | 18673 | result_loc->written = true; |
| 18672 | 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 | 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 | 22949 | ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes, |
| 22948 | 22950 | ref_type->data.pointer.allow_zero); |
| 22949 | 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 | 22953 | } else { |
| 22952 | 22954 | ir_add_error(ira, &instruction->base.base, |
| 22953 | 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 | 23032 | ref_type->data.pointer.bit_offset_in_host, ref_type->data.pointer.host_int_bytes, |
| 23031 | 23033 | ref_type->data.pointer.allow_zero); |
| 23032 | 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 | 23038 | return target_value_ptr; |
| ... | ... | @@ -27814,7 +27816,8 @@ static IrInstGen *ir_align_cast(IrAnalyze *ira, IrInstGen *target, uint32_t alig |
| 27814 | 27816 | } |
| 27815 | 27817 | |
| 27816 | 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 | 27822 | Error err; |
| 27820 | 27823 | |
| ... | ... | @@ -27853,14 +27856,16 @@ static IrInstGen *ir_analyze_ptr_cast(IrAnalyze *ira, IrInst* source_instr, IrIn |
| 27853 | 27856 | ir_add_error(ira, source_instr, buf_sprintf("cast discards const qualifier")); |
| 27854 | 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 | 27859 | uint32_t dest_align_bytes; |
| 27861 | 27860 | if ((err = resolve_ptr_align(ira, dest_type, &dest_align_bytes))) |
| 27862 | 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 | 27869 | if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) |
| 27865 | 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 | 27940 | } |
| 27936 | 27941 | result->value->type = dest_type; |
| 27937 | 27942 | |
| 27938 | | // Keep the bigger alignment, it can only help- |
| 27939 | | // unless the target is zero bits. |
| 27940 | | if (src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) { |
| 27943 | // Keep the bigger alignment, it can only help- unless the target is zero bits. |
| 27944 | if (keep_bigger_alignment && src_align_bytes > dest_align_bytes && type_has_bits(ira->codegen, dest_type)) { |
| 27941 | 27945 | result = ir_align_cast(ira, result, src_align_bytes, false); |
| 27942 | 27946 | } |
| 27943 | 27947 | |
| 27944 | 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 | 27952 | ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); |
| 27949 | 27953 | add_error_note(ira->codegen, msg, ptr_src->source_node, |
| 27950 | 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 | 27959 | |
| 27956 | 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- |
| 27959 | | // unless the target is zero bits. |
| 27962 | // Keep the bigger alignment, it can only help- unless the target is zero bits. |
| 27960 | 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 | 27965 | result = ir_align_cast(ira, casted_ptr, src_align_bytes, false); |
| 27963 | 27966 | if (type_is_invalid(result->value->type)) |
| 27964 | 27967 | return ira->codegen->invalid_inst_gen; |
| ... | ... | @@ -27979,8 +27982,9 @@ static IrInstGen *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstSrcPtrCa |
| 27979 | 27982 | if (type_is_invalid(src_type)) |
| 27980 | 27983 | return ira->codegen->invalid_inst_gen; |
| 27981 | 27984 | |
| 27985 | bool keep_bigger_alignment = true; |
| 27982 | 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 | 27990 | static void buf_write_value_bytes_array(CodeGen *codegen, uint8_t *buf, ZigValue *val, size_t len) { |