| ... | ... | @@ -68,6 +68,7 @@ enum ConstCastResultId { |
| 68 | 68 | ConstCastResultIdBadAllowsZero, |
| 69 | 69 | ConstCastResultIdArrayChild, |
| 70 | 70 | ConstCastResultIdBadNullTermArrays, |
| 71 | ConstCastResultIdPtrLens, |
| 71 | 72 | }; |
| 72 | 73 | |
| 73 | 74 | struct ConstCastOnly; |
| ... | ... | @@ -92,6 +93,7 @@ struct ConstCastTypeMismatch; |
| 92 | 93 | struct ConstCastArrayMismatch; |
| 93 | 94 | struct ConstCastBadAllowsZero; |
| 94 | 95 | struct ConstCastBadNullTermArrays; |
| 96 | struct ConstCastBadPtrLens; |
| 95 | 97 | |
| 96 | 98 | struct ConstCastOnly { |
| 97 | 99 | ConstCastResultId id; |
| ... | ... | @@ -110,6 +112,7 @@ struct ConstCastOnly { |
| 110 | 112 | ConstCastArgNoAlias arg_no_alias; |
| 111 | 113 | ConstCastBadAllowsZero *bad_allows_zero; |
| 112 | 114 | ConstCastBadNullTermArrays *bad_null_term_arrays; |
| 115 | ConstCastBadPtrLens *bad_ptr_lens; |
| 113 | 116 | } data; |
| 114 | 117 | }; |
| 115 | 118 | |
| ... | ... | @@ -169,6 +172,11 @@ struct ConstCastBadNullTermArrays { |
| 169 | 172 | ZigType *actual_type; |
| 170 | 173 | }; |
| 171 | 174 | |
| 175 | struct ConstCastBadPtrLens { |
| 176 | ZigType *wanted_type; |
| 177 | ZigType *actual_type; |
| 178 | }; |
| 179 | |
| 172 | 180 | |
| 173 | 181 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); |
| 174 | 182 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval, |
| ... | ... | @@ -9843,6 +9851,18 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted |
| 9843 | 9851 | bool actual_opt_or_ptr = actual_ptr_type != nullptr && |
| 9844 | 9852 | (actual_type->id == ZigTypeIdPointer || actual_type->id == ZigTypeIdOptional); |
| 9845 | 9853 | if (wanted_opt_or_ptr && actual_opt_or_ptr) { |
| 9854 | bool ptr_lens_equal = actual_ptr_type->data.pointer.ptr_len == wanted_ptr_type->data.pointer.ptr_len; |
| 9855 | bool ok_null_term_ptrs = |
| 9856 | actual_ptr_type->data.pointer.ptr_len == PtrLenNull || |
| 9857 | wanted_ptr_type->data.pointer.ptr_len == PtrLenUnknown; |
| 9858 | if (!(ptr_lens_equal || wanted_is_c_ptr || actual_is_c_ptr || ok_null_term_ptrs)) { |
| 9859 | result.id = ConstCastResultIdPtrLens; |
| 9860 | result.data.bad_ptr_lens = allocate_nonzero<ConstCastBadPtrLens>(1); |
| 9861 | result.data.bad_ptr_lens->wanted_type = wanted_type; |
| 9862 | result.data.bad_ptr_lens->actual_type = actual_type; |
| 9863 | return result; |
| 9864 | } |
| 9865 | |
| 9846 | 9866 | ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type, |
| 9847 | 9867 | actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const); |
| 9848 | 9868 | if (child.id == ConstCastResultIdInvalid) |
| ... | ... | @@ -9881,12 +9901,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted |
| 9881 | 9901 | result.id = ConstCastResultIdInvalid; |
| 9882 | 9902 | return result; |
| 9883 | 9903 | } |
| 9884 | | bool ptr_lens_equal = actual_ptr_type->data.pointer.ptr_len == wanted_ptr_type->data.pointer.ptr_len; |
| 9885 | | bool ok_null_term_ptrs = |
| 9886 | | actual_ptr_type->data.pointer.ptr_len == PtrLenNull || |
| 9887 | | wanted_ptr_type->data.pointer.ptr_len == PtrLenUnknown; |
| 9888 | | if ((ptr_lens_equal || wanted_is_c_ptr || actual_is_c_ptr || ok_null_term_ptrs) && |
| 9889 | | type_has_bits(wanted_type) == type_has_bits(actual_type) && |
| 9904 | if (type_has_bits(wanted_type) == type_has_bits(actual_type) && |
| 9890 | 9905 | (!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) && |
| 9891 | 9906 | (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) && |
| 9892 | 9907 | actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host && |
| ... | ... | @@ -12569,6 +12584,17 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa |
| 12569 | 12584 | } |
| 12570 | 12585 | break; |
| 12571 | 12586 | } |
| 12587 | case ConstCastResultIdPtrLens: { |
| 12588 | ZigType *wanted_type = cast_result->data.bad_ptr_lens->wanted_type; |
| 12589 | ZigType *actual_type = cast_result->data.bad_ptr_lens->actual_type; |
| 12590 | bool wanted_null_term = wanted_type->data.pointer.ptr_len == PtrLenNull; |
| 12591 | bool actual_null_term = actual_type->data.pointer.ptr_len == PtrLenNull; |
| 12592 | if (wanted_null_term && !actual_null_term) { |
| 12593 | add_error_note(ira->codegen, parent_msg, source_node, |
| 12594 | buf_sprintf("destination type requires null termination")); |
| 12595 | } |
| 12596 | break; |
| 12597 | } |
| 12572 | 12598 | case ConstCastResultIdFnIsGeneric: |
| 12573 | 12599 | add_error_note(ira->codegen, parent_msg, source_node, |
| 12574 | 12600 | buf_sprintf("only one of the functions is generic")); |