| ... | ... | @@ -67,9 +67,10 @@ enum ConstCastResultId { |
| 67 | 67 | ConstCastResultIdAsyncAllocatorType, |
| 68 | 68 | ConstCastResultIdBadAllowsZero, |
| 69 | 69 | ConstCastResultIdArrayChild, |
| 70 | | ConstCastResultIdBadNullTermArrays, |
| 70 | ConstCastResultIdSentinelArrays, |
| 71 | 71 | ConstCastResultIdPtrLens, |
| 72 | 72 | ConstCastResultIdCV, |
| 73 | ConstCastResultIdPtrSentinel, |
| 73 | 74 | }; |
| 74 | 75 | |
| 75 | 76 | struct ConstCastOnly; |
| ... | ... | @@ -94,8 +95,8 @@ struct ConstCastTypeMismatch; |
| 94 | 95 | struct ConstCastArrayMismatch; |
| 95 | 96 | struct ConstCastBadAllowsZero; |
| 96 | 97 | struct ConstCastBadNullTermArrays; |
| 97 | | struct ConstCastBadPtrLens; |
| 98 | 98 | struct ConstCastBadCV; |
| 99 | struct ConstCastPtrSentinel; |
| 99 | 100 | |
| 100 | 101 | struct ConstCastOnly { |
| 101 | 102 | ConstCastResultId id; |
| ... | ... | @@ -113,9 +114,9 @@ struct ConstCastOnly { |
| 113 | 114 | ConstCastArg fn_arg; |
| 114 | 115 | ConstCastArgNoAlias arg_no_alias; |
| 115 | 116 | ConstCastBadAllowsZero *bad_allows_zero; |
| 116 | | ConstCastBadNullTermArrays *bad_null_term_arrays; |
| 117 | | ConstCastBadPtrLens *bad_ptr_lens; |
| 117 | ConstCastBadNullTermArrays *sentinel_arrays; |
| 118 | 118 | ConstCastBadCV *bad_cv; |
| 119 | ConstCastPtrSentinel *bad_ptr_sentinel; |
| 119 | 120 | } data; |
| 120 | 121 | }; |
| 121 | 122 | |
| ... | ... | @@ -175,14 +176,13 @@ struct ConstCastBadNullTermArrays { |
| 175 | 176 | ZigType *actual_type; |
| 176 | 177 | }; |
| 177 | 178 | |
| 178 | | struct ConstCastBadPtrLens { |
| 179 | struct ConstCastBadCV { |
| 179 | 180 | ZigType *wanted_type; |
| 180 | 181 | ZigType *actual_type; |
| 181 | 182 | }; |
| 182 | 183 | |
| 183 | | struct ConstCastBadCV { |
| 184 | struct ConstCastPtrSentinel { |
| 184 | 185 | ZigType *wanted_type; |
| 185 | | ZigType *actual_type; |
| 186 | 186 | }; |
| 187 | 187 | |
| 188 | 188 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); |
| ... | ... | @@ -264,8 +264,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c |
| 264 | 264 | case ConstPtrSpecialBaseArray: { |
| 265 | 265 | ConstExprValue *array_val = const_val->data.x_ptr.data.base_array.array_val; |
| 266 | 266 | if (const_val->data.x_ptr.data.base_array.elem_index == array_val->type->data.array.len) { |
| 267 | | assert(array_val->type->data.array.is_null_terminated); |
| 268 | | result = get_null_value(array_val->type->data.array.child_type); |
| 267 | result = array_val->type->data.array.sentinel; |
| 269 | 268 | } else { |
| 270 | 269 | expand_undef_array(g, array_val); |
| 271 | 270 | result = &array_val->data.x_array.data.s_none.elements[const_val->data.x_ptr.data.base_array.elem_index]; |
| ... | ... | @@ -317,7 +316,7 @@ static bool slice_is_const(ZigType *type) { |
| 317 | 316 | |
| 318 | 317 | // This function returns true when you can change the type of a ConstExprValue and the |
| 319 | 318 | // value remains meaningful. |
| 320 | | static bool types_have_same_zig_comptime_repr(ZigType *expected, ZigType *actual) { |
| 319 | static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expected, ZigType *actual) { |
| 321 | 320 | if (expected == actual) |
| 322 | 321 | return true; |
| 323 | 322 | |
| ... | ... | @@ -366,7 +365,8 @@ static bool types_have_same_zig_comptime_repr(ZigType *expected, ZigType *actual |
| 366 | 365 | case ZigTypeIdArray: |
| 367 | 366 | return expected->data.array.len == actual->data.array.len && |
| 368 | 367 | expected->data.array.child_type == actual->data.array.child_type && |
| 369 | | (!expected->data.array.is_null_terminated || actual->data.array.is_null_terminated); |
| 368 | (expected->data.array.sentinel == nullptr || (actual->data.array.sentinel != nullptr && |
| 369 | const_values_equal(codegen, expected->data.array.sentinel, actual->data.array.sentinel))); |
| 370 | 370 | } |
| 371 | 371 | zig_unreachable(); |
| 372 | 372 | } |
| ... | ... | @@ -1576,9 +1576,11 @@ static IrInstruction *ir_build_br(IrBuilder *irb, Scope *scope, AstNode *source_ |
| 1576 | 1576 | |
| 1577 | 1577 | static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1578 | 1578 | IrInstruction *child_type, bool is_const, bool is_volatile, PtrLen ptr_len, |
| 1579 | | IrInstruction *align_value, uint32_t bit_offset_start, uint32_t host_int_bytes, bool is_allow_zero) |
| 1579 | IrInstruction *sentinel, IrInstruction *align_value, |
| 1580 | uint32_t bit_offset_start, uint32_t host_int_bytes, bool is_allow_zero) |
| 1580 | 1581 | { |
| 1581 | 1582 | IrInstructionPtrType *ptr_type_of_instruction = ir_build_instruction<IrInstructionPtrType>(irb, scope, source_node); |
| 1583 | ptr_type_of_instruction->sentinel = sentinel; |
| 1582 | 1584 | ptr_type_of_instruction->align_value = align_value; |
| 1583 | 1585 | ptr_type_of_instruction->child_type = child_type; |
| 1584 | 1586 | ptr_type_of_instruction->is_const = is_const; |
| ... | ... | @@ -1588,6 +1590,7 @@ static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *s |
| 1588 | 1590 | ptr_type_of_instruction->host_int_bytes = host_int_bytes; |
| 1589 | 1591 | ptr_type_of_instruction->is_allow_zero = is_allow_zero; |
| 1590 | 1592 | |
| 1593 | if (sentinel) ir_ref_instruction(sentinel, irb->current_basic_block); |
| 1591 | 1594 | if (align_value) ir_ref_instruction(align_value, irb->current_basic_block); |
| 1592 | 1595 | ir_ref_instruction(child_type, irb->current_basic_block); |
| 1593 | 1596 | |
| ... | ... | @@ -1804,14 +1807,15 @@ static IrInstruction *ir_build_set_float_mode(IrBuilder *irb, Scope *scope, AstN |
| 1804 | 1807 | } |
| 1805 | 1808 | |
| 1806 | 1809 | static IrInstruction *ir_build_array_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *size, |
| 1807 | | IrInstruction *child_type, bool is_null_terminated) |
| 1810 | IrInstruction *sentinel, IrInstruction *child_type) |
| 1808 | 1811 | { |
| 1809 | 1812 | IrInstructionArrayType *instruction = ir_build_instruction<IrInstructionArrayType>(irb, scope, source_node); |
| 1810 | 1813 | instruction->size = size; |
| 1814 | instruction->sentinel = sentinel; |
| 1811 | 1815 | instruction->child_type = child_type; |
| 1812 | | instruction->is_null_terminated = is_null_terminated; |
| 1813 | 1816 | |
| 1814 | 1817 | ir_ref_instruction(size, irb->current_basic_block); |
| 1818 | if (sentinel != nullptr) ir_ref_instruction(sentinel, irb->current_basic_block); |
| 1815 | 1819 | ir_ref_instruction(child_type, irb->current_basic_block); |
| 1816 | 1820 | |
| 1817 | 1821 | return &instruction->base; |
| ... | ... | @@ -1827,20 +1831,22 @@ static IrInstruction *ir_build_anyframe_type(IrBuilder *irb, Scope *scope, AstNo |
| 1827 | 1831 | |
| 1828 | 1832 | return &instruction->base; |
| 1829 | 1833 | } |
| 1834 | |
| 1830 | 1835 | static IrInstruction *ir_build_slice_type(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1831 | | IrInstruction *child_type, bool is_const, bool is_volatile, IrInstruction *align_value, bool is_allow_zero, |
| 1832 | | bool is_null_terminated) |
| 1836 | IrInstruction *child_type, bool is_const, bool is_volatile, |
| 1837 | IrInstruction *sentinel, IrInstruction *align_value, bool is_allow_zero) |
| 1833 | 1838 | { |
| 1834 | 1839 | IrInstructionSliceType *instruction = ir_build_instruction<IrInstructionSliceType>(irb, scope, source_node); |
| 1835 | 1840 | instruction->is_const = is_const; |
| 1836 | 1841 | instruction->is_volatile = is_volatile; |
| 1837 | 1842 | instruction->child_type = child_type; |
| 1843 | instruction->sentinel = sentinel; |
| 1838 | 1844 | instruction->align_value = align_value; |
| 1839 | 1845 | instruction->is_allow_zero = is_allow_zero; |
| 1840 | | instruction->is_null_terminated = is_null_terminated; |
| 1841 | 1846 | |
| 1847 | if (sentinel != nullptr) ir_ref_instruction(sentinel, irb->current_basic_block); |
| 1848 | if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); |
| 1842 | 1849 | ir_ref_instruction(child_type, irb->current_basic_block); |
| 1843 | | if (align_value) ir_ref_instruction(align_value, irb->current_basic_block); |
| 1844 | 1850 | |
| 1845 | 1851 | return &instruction->base; |
| 1846 | 1852 | } |
| ... | ... | @@ -6067,9 +6073,9 @@ static PtrLen star_token_to_ptr_len(TokenId token_id) { |
| 6067 | 6073 | case TokenIdStar: |
| 6068 | 6074 | case TokenIdStarStar: |
| 6069 | 6075 | return PtrLenSingle; |
| 6070 | | case TokenIdBracketStarBracket: |
| 6076 | case TokenIdLBracket: |
| 6071 | 6077 | return PtrLenUnknown; |
| 6072 | | case TokenIdBracketStarCBracket: |
| 6078 | case TokenIdSymbol: |
| 6073 | 6079 | return PtrLenC; |
| 6074 | 6080 | default: |
| 6075 | 6081 | zig_unreachable(); |
| ... | ... | @@ -6080,22 +6086,22 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode |
| 6080 | 6086 | assert(node->type == NodeTypePointerType); |
| 6081 | 6087 | |
| 6082 | 6088 | PtrLen ptr_len = star_token_to_ptr_len(node->data.pointer_type.star_token->id); |
| 6083 | | if (node->data.pointer_type.is_null_terminated) { |
| 6084 | | if (ptr_len == PtrLenUnknown) { |
| 6085 | | ptr_len = PtrLenNull; |
| 6086 | | } else { |
| 6087 | | exec_add_error_node(irb->codegen, irb->exec, node, |
| 6088 | | buf_sprintf("null-terminated pointer must be specified with [*] token")); |
| 6089 | | return irb->codegen->invalid_instruction; |
| 6090 | | } |
| 6091 | | } |
| 6092 | 6089 | |
| 6093 | 6090 | bool is_const = node->data.pointer_type.is_const; |
| 6094 | 6091 | bool is_volatile = node->data.pointer_type.is_volatile; |
| 6095 | 6092 | bool is_allow_zero = node->data.pointer_type.allow_zero_token != nullptr; |
| 6093 | AstNode *sentinel_expr = node->data.pointer_type.sentinel; |
| 6096 | 6094 | AstNode *expr_node = node->data.pointer_type.op_expr; |
| 6097 | 6095 | AstNode *align_expr = node->data.pointer_type.align_expr; |
| 6098 | 6096 | |
| 6097 | IrInstruction *sentinel; |
| 6098 | if (sentinel_expr != nullptr) { |
| 6099 | sentinel = ir_gen_node(irb, sentinel_expr, scope); |
| 6100 | if (sentinel == irb->codegen->invalid_instruction) |
| 6101 | return sentinel; |
| 6102 | } else { |
| 6103 | sentinel = nullptr; |
| 6104 | } |
| 6099 | 6105 | |
| 6100 | 6106 | IrInstruction *align_value; |
| 6101 | 6107 | if (align_expr != nullptr) { |
| ... | ... | @@ -6141,7 +6147,7 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode |
| 6141 | 6147 | } |
| 6142 | 6148 | |
| 6143 | 6149 | return ir_build_ptr_type(irb, scope, node, child_type, is_const, is_volatile, |
| 6144 | | ptr_len, align_value, bit_offset_start, host_int_bytes, is_allow_zero); |
| 6150 | ptr_len, sentinel, align_value, bit_offset_start, host_int_bytes, is_allow_zero); |
| 6145 | 6151 | } |
| 6146 | 6152 | |
| 6147 | 6153 | static IrInstruction *ir_gen_catch_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| ... | ... | @@ -6245,13 +6251,22 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A |
| 6245 | 6251 | buf_sprintf("initializing array with struct syntax")); |
| 6246 | 6252 | return irb->codegen->invalid_instruction; |
| 6247 | 6253 | } |
| 6254 | IrInstruction *sentinel; |
| 6255 | if (container_init_expr->type->data.inferred_array_type.sentinel != nullptr) { |
| 6256 | sentinel = ir_gen_node(irb, container_init_expr->type->data.inferred_array_type.sentinel, scope); |
| 6257 | if (sentinel == irb->codegen->invalid_instruction) |
| 6258 | return sentinel; |
| 6259 | } else { |
| 6260 | sentinel = nullptr; |
| 6261 | } |
| 6262 | |
| 6248 | 6263 | IrInstruction *elem_type = ir_gen_node(irb, |
| 6249 | 6264 | container_init_expr->type->data.inferred_array_type.child_type, scope); |
| 6250 | 6265 | if (elem_type == irb->codegen->invalid_instruction) |
| 6251 | 6266 | return elem_type; |
| 6252 | 6267 | size_t item_count = container_init_expr->entries.length; |
| 6253 | 6268 | IrInstruction *item_count_inst = ir_build_const_usize(irb, scope, node, item_count); |
| 6254 | | container_type = ir_build_array_type(irb, scope, node, item_count_inst, elem_type, false); |
| 6269 | container_type = ir_build_array_type(irb, scope, node, item_count_inst, sentinel, elem_type); |
| 6255 | 6270 | } else { |
| 6256 | 6271 | container_type = ir_gen_node(irb, container_init_expr->type, scope); |
| 6257 | 6272 | if (container_type == irb->codegen->invalid_instruction) |
| ... | ... | @@ -6975,10 +6990,20 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *n |
| 6975 | 6990 | bool is_const = node->data.array_type.is_const; |
| 6976 | 6991 | bool is_volatile = node->data.array_type.is_volatile; |
| 6977 | 6992 | bool is_allow_zero = node->data.array_type.allow_zero_token != nullptr; |
| 6978 | | bool is_null_terminated = node->data.array_type.is_null_terminated; |
| 6993 | AstNode *sentinel_expr = node->data.array_type.sentinel; |
| 6979 | 6994 | AstNode *align_expr = node->data.array_type.align_expr; |
| 6980 | 6995 | |
| 6981 | 6996 | Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); |
| 6997 | |
| 6998 | IrInstruction *sentinel; |
| 6999 | if (sentinel_expr != nullptr) { |
| 7000 | sentinel = ir_gen_node(irb, sentinel_expr, comptime_scope); |
| 7001 | if (sentinel == irb->codegen->invalid_instruction) |
| 7002 | return sentinel; |
| 7003 | } else { |
| 7004 | sentinel = nullptr; |
| 7005 | } |
| 7006 | |
| 6982 | 7007 | if (size_node) { |
| 6983 | 7008 | if (is_const) { |
| 6984 | 7009 | add_node_error(irb->codegen, node, buf_create_from_str("const qualifier invalid on array type")); |
| ... | ... | @@ -7005,7 +7030,7 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *n |
| 7005 | 7030 | if (child_type == irb->codegen->invalid_instruction) |
| 7006 | 7031 | return child_type; |
| 7007 | 7032 | |
| 7008 | | return ir_build_array_type(irb, scope, node, size_value, child_type, is_null_terminated); |
| 7033 | return ir_build_array_type(irb, scope, node, size_value, sentinel, child_type); |
| 7009 | 7034 | } else { |
| 7010 | 7035 | IrInstruction *align_value; |
| 7011 | 7036 | if (align_expr != nullptr) { |
| ... | ... | @@ -7020,8 +7045,8 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *n |
| 7020 | 7045 | if (child_type == irb->codegen->invalid_instruction) |
| 7021 | 7046 | return child_type; |
| 7022 | 7047 | |
| 7023 | | return ir_build_slice_type(irb, scope, node, child_type, is_const, is_volatile, align_value, is_allow_zero, |
| 7024 | | is_null_terminated); |
| 7048 | return ir_build_slice_type(irb, scope, node, child_type, is_const, is_volatile, sentinel, |
| 7049 | align_value, is_allow_zero); |
| 7025 | 7050 | } |
| 7026 | 7051 | } |
| 7027 | 7052 | |
| ... | ... | @@ -8698,7 +8723,7 @@ ConstExprValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ConstExprVal |
| 8698 | 8723 | case OnePossibleValueYes: |
| 8699 | 8724 | return get_the_one_possible_value(codegen, expected_type); |
| 8700 | 8725 | } |
| 8701 | | if (!types_have_same_zig_comptime_repr(expected_type, val->type)) { |
| 8726 | if (!types_have_same_zig_comptime_repr(codegen, expected_type, val->type)) { |
| 8702 | 8727 | if ((err = eval_comptime_ptr_reinterpret(ira, codegen, source_node, const_val))) |
| 8703 | 8728 | return nullptr; |
| 8704 | 8729 | return const_ptr_pointee_unchecked(codegen, const_val); |
| ... | ... | @@ -9846,7 +9871,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted |
| 9846 | 9871 | // alignment can be decreased |
| 9847 | 9872 | // bit offset attributes must match exactly |
| 9848 | 9873 | // PtrLenSingle/PtrLenUnknown must match exactly, but PtrLenC matches either one |
| 9849 | | // PtrLenNull can coerce into PtrLenUnknown |
| 9874 | // sentinel-terminated pointers can coerce into PtrLenUnknown |
| 9850 | 9875 | ZigType *wanted_ptr_type = get_src_ptr_type(wanted_type); |
| 9851 | 9876 | ZigType *actual_ptr_type = get_src_ptr_type(actual_type); |
| 9852 | 9877 | bool wanted_allows_zero = ptr_allows_addr_zero(wanted_type); |
| ... | ... | @@ -9858,15 +9883,20 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted |
| 9858 | 9883 | bool actual_opt_or_ptr = actual_ptr_type != nullptr && |
| 9859 | 9884 | (actual_type->id == ZigTypeIdPointer || actual_type->id == ZigTypeIdOptional); |
| 9860 | 9885 | if (wanted_opt_or_ptr && actual_opt_or_ptr) { |
| 9861 | | bool ptr_lens_equal = actual_ptr_type->data.pointer.ptr_len == wanted_ptr_type->data.pointer.ptr_len; |
| 9862 | 9886 | bool ok_null_term_ptrs = |
| 9863 | | actual_ptr_type->data.pointer.ptr_len == PtrLenNull || |
| 9864 | | wanted_ptr_type->data.pointer.ptr_len == PtrLenUnknown; |
| 9865 | | if (!(ptr_lens_equal || wanted_is_c_ptr || actual_is_c_ptr || ok_null_term_ptrs)) { |
| 9887 | wanted_ptr_type->data.pointer.sentinel == nullptr || |
| 9888 | (actual_ptr_type->data.pointer.sentinel != nullptr && |
| 9889 | const_values_equal(ira->codegen, wanted_ptr_type->data.pointer.sentinel, |
| 9890 | actual_ptr_type->data.pointer.sentinel)); |
| 9891 | if (!ok_null_term_ptrs) { |
| 9892 | result.id = ConstCastResultIdPtrSentinel; |
| 9893 | result.data.bad_ptr_sentinel = allocate_nonzero<ConstCastPtrSentinel>(1); |
| 9894 | result.data.bad_ptr_sentinel->wanted_type = wanted_type; |
| 9895 | return result; |
| 9896 | } |
| 9897 | bool ptr_lens_equal = actual_ptr_type->data.pointer.ptr_len == wanted_ptr_type->data.pointer.ptr_len; |
| 9898 | if (!(ptr_lens_equal || wanted_is_c_ptr || actual_is_c_ptr)) { |
| 9866 | 9899 | result.id = ConstCastResultIdPtrLens; |
| 9867 | | result.data.bad_ptr_lens = allocate_nonzero<ConstCastBadPtrLens>(1); |
| 9868 | | result.data.bad_ptr_lens->wanted_type = wanted_type; |
| 9869 | | result.data.bad_ptr_lens->actual_type = actual_type; |
| 9870 | 9900 | return result; |
| 9871 | 9901 | } |
| 9872 | 9902 | |
| ... | ... | @@ -9944,14 +9974,15 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted |
| 9944 | 9974 | result.data.array_mismatch->actual_child = actual_type->data.array.child_type; |
| 9945 | 9975 | return result; |
| 9946 | 9976 | } |
| 9947 | | bool ok_null_terminated = !wanted_type->data.array.is_null_terminated || |
| 9948 | | actual_type->data.array.is_null_terminated; |
| 9977 | bool ok_null_terminated = (wanted_type->data.array.sentinel == nullptr) || |
| 9978 | (actual_type->data.array.sentinel != nullptr && |
| 9979 | const_values_equal(ira->codegen, wanted_type->data.array.sentinel, actual_type->data.array.sentinel)); |
| 9949 | 9980 | if (!ok_null_terminated) { |
| 9950 | | result.id = ConstCastResultIdBadNullTermArrays; |
| 9951 | | result.data.bad_null_term_arrays = allocate_nonzero<ConstCastBadNullTermArrays>(1); |
| 9952 | | result.data.bad_null_term_arrays->child = child; |
| 9953 | | result.data.bad_null_term_arrays->wanted_type = wanted_type; |
| 9954 | | result.data.bad_null_term_arrays->actual_type = actual_type; |
| 9981 | result.id = ConstCastResultIdSentinelArrays; |
| 9982 | result.data.sentinel_arrays = allocate_nonzero<ConstCastBadNullTermArrays>(1); |
| 9983 | result.data.sentinel_arrays->child = child; |
| 9984 | result.data.sentinel_arrays->wanted_type = wanted_type; |
| 9985 | result.data.sentinel_arrays->actual_type = actual_type; |
| 9955 | 9986 | return result; |
| 9956 | 9987 | } |
| 9957 | 9988 | return result; |
| ... | ... | @@ -10781,8 +10812,12 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 10781 | 10812 | prev_type->data.pointer.child_type->id == ZigTypeIdArray && |
| 10782 | 10813 | (cur_type->data.pointer.is_const || !prev_type->data.pointer.is_const || |
| 10783 | 10814 | prev_type->data.pointer.child_type->data.array.len == 0) && |
| 10784 | | (cur_type->data.pointer.child_type->data.array.is_null_terminated || |
| 10785 | | !prev_type->data.pointer.child_type->data.array.is_null_terminated) && |
| 10815 | ( |
| 10816 | prev_type->data.pointer.child_type->data.array.sentinel == nullptr || |
| 10817 | (cur_type->data.pointer.child_type->data.array.sentinel != nullptr && |
| 10818 | const_values_equal(ira->codegen, prev_type->data.pointer.child_type->data.array.sentinel, |
| 10819 | cur_type->data.pointer.child_type->data.array.sentinel)) |
| 10820 | ) && |
| 10786 | 10821 | types_match_const_cast_only(ira, |
| 10787 | 10822 | cur_type->data.pointer.child_type->data.array.child_type, |
| 10788 | 10823 | prev_type->data.pointer.child_type->data.array.child_type, |
| ... | ... | @@ -10798,8 +10833,12 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 10798 | 10833 | cur_type->data.pointer.child_type->id == ZigTypeIdArray && |
| 10799 | 10834 | (prev_type->data.pointer.is_const || !cur_type->data.pointer.is_const || |
| 10800 | 10835 | cur_type->data.pointer.child_type->data.array.len == 0) && |
| 10801 | | (prev_type->data.pointer.child_type->data.array.is_null_terminated || |
| 10802 | | !cur_type->data.pointer.child_type->data.array.is_null_terminated) && |
| 10836 | ( |
| 10837 | cur_type->data.pointer.child_type->data.array.sentinel == nullptr || |
| 10838 | (prev_type->data.pointer.child_type->data.array.sentinel != nullptr && |
| 10839 | const_values_equal(ira->codegen, cur_type->data.pointer.child_type->data.array.sentinel, |
| 10840 | prev_type->data.pointer.child_type->data.array.sentinel)) |
| 10841 | ) && |
| 10803 | 10842 | types_match_const_cast_only(ira, |
| 10804 | 10843 | prev_type->data.pointer.child_type->data.array.child_type, |
| 10805 | 10844 | cur_type->data.pointer.child_type->data.array.child_type, |
| ... | ... | @@ -10871,11 +10910,12 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 10871 | 10910 | } else if (prev_inst->value.type->id == ZigTypeIdPointer) { |
| 10872 | 10911 | ZigType *array_type = prev_inst->value.type->data.pointer.child_type; |
| 10873 | 10912 | src_assert(array_type->id == ZigTypeIdArray, source_node); |
| 10874 | | ZigType *ptr_type = get_pointer_to_type_extra( |
| 10913 | ZigType *ptr_type = get_pointer_to_type_extra2( |
| 10875 | 10914 | ira->codegen, array_type->data.array.child_type, |
| 10876 | 10915 | prev_inst->value.type->data.pointer.is_const, false, |
| 10877 | | array_type->data.array.is_null_terminated ? PtrLenNull : PtrLenUnknown, |
| 10878 | | 0, 0, 0, false); |
| 10916 | PtrLenUnknown, |
| 10917 | 0, 0, 0, false, |
| 10918 | VECTOR_INDEX_NONE, nullptr, array_type->data.array.sentinel); |
| 10879 | 10919 | ZigType *slice_type = get_slice_type(ira->codegen, ptr_type); |
| 10880 | 10920 | if (err_set_type != nullptr) { |
| 10881 | 10921 | return get_error_union_type(ira->codegen, err_set_type, slice_type); |
| ... | ... | @@ -11682,7 +11722,7 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so |
| 11682 | 11722 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, |
| 11683 | 11723 | source_instr->scope, source_instr->source_node); |
| 11684 | 11724 | const_instruction->base.value.special = ConstValSpecialStatic; |
| 11685 | | if (types_have_same_zig_comptime_repr(wanted_type, payload_type)) { |
| 11725 | if (types_have_same_zig_comptime_repr(ira->codegen, wanted_type, payload_type)) { |
| 11686 | 11726 | copy_const_val(&const_instruction->base.value, val, val->data.x_ptr.mut == ConstPtrMutComptimeConst); |
| 11687 | 11727 | } else { |
| 11688 | 11728 | const_instruction->base.value.data.x_optional = val; |
| ... | ... | @@ -12601,14 +12641,24 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa |
| 12601 | 12641 | break; |
| 12602 | 12642 | } |
| 12603 | 12643 | case ConstCastResultIdPtrLens: { |
| 12604 | | ZigType *wanted_type = cast_result->data.bad_ptr_lens->wanted_type; |
| 12605 | | ZigType *actual_type = cast_result->data.bad_ptr_lens->actual_type; |
| 12606 | | bool wanted_null_term = wanted_type->data.pointer.ptr_len == PtrLenNull; |
| 12607 | | bool actual_null_term = actual_type->data.pointer.ptr_len == PtrLenNull; |
| 12608 | | if (wanted_null_term && !actual_null_term) { |
| 12609 | | add_error_note(ira->codegen, parent_msg, source_node, |
| 12610 | | buf_sprintf("destination type requires null termination")); |
| 12611 | | } |
| 12644 | add_error_note(ira->codegen, parent_msg, source_node, |
| 12645 | buf_sprintf("pointer length mismatch")); |
| 12646 | break; |
| 12647 | } |
| 12648 | case ConstCastResultIdPtrSentinel: { |
| 12649 | ZigType *wanted_type = cast_result->data.bad_ptr_sentinel->wanted_type; |
| 12650 | Buf *msg = buf_sprintf("destination pointer requires a terminating '"); |
| 12651 | render_const_value(ira->codegen, msg, wanted_type->data.pointer.sentinel); |
| 12652 | buf_appendf(msg, "' sentinel value"); |
| 12653 | add_error_note(ira->codegen, parent_msg, source_node, msg); |
| 12654 | break; |
| 12655 | } |
| 12656 | case ConstCastResultIdSentinelArrays: { |
| 12657 | ZigType *wanted_type = cast_result->data.sentinel_arrays->wanted_type; |
| 12658 | Buf *msg = buf_sprintf("destination array requires a terminating '"); |
| 12659 | render_const_value(ira->codegen, msg, wanted_type->data.pointer.sentinel); |
| 12660 | buf_appendf(msg, "' sentinel value"); |
| 12661 | add_error_note(ira->codegen, parent_msg, source_node, msg); |
| 12612 | 12662 | break; |
| 12613 | 12663 | } |
| 12614 | 12664 | case ConstCastResultIdCV: { |
| ... | ... | @@ -12642,7 +12692,6 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa |
| 12642 | 12692 | case ConstCastResultIdUnresolvedInferredErrSet: // TODO |
| 12643 | 12693 | case ConstCastResultIdAsyncAllocatorType: // TODO |
| 12644 | 12694 | case ConstCastResultIdArrayChild: // TODO |
| 12645 | | case ConstCastResultIdBadNullTermArrays: // TODO |
| 12646 | 12695 | break; |
| 12647 | 12696 | } |
| 12648 | 12697 | } |
| ... | ... | @@ -13013,16 +13062,18 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 13013 | 13062 | |
| 13014 | 13063 | // *[N]T to [*]T and [*c]T |
| 13015 | 13064 | if (wanted_type->id == ZigTypeIdPointer && |
| 13016 | | (wanted_type->data.pointer.ptr_len == PtrLenUnknown || wanted_type->data.pointer.ptr_len == PtrLenC || |
| 13017 | | wanted_type->data.pointer.ptr_len == PtrLenNull) && |
| 13065 | (wanted_type->data.pointer.ptr_len == PtrLenUnknown || wanted_type->data.pointer.ptr_len == PtrLenC) && |
| 13018 | 13066 | actual_type->id == ZigTypeIdPointer && |
| 13019 | 13067 | actual_type->data.pointer.ptr_len == PtrLenSingle && |
| 13020 | 13068 | actual_type->data.pointer.child_type->id == ZigTypeIdArray && |
| 13021 | 13069 | (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) && |
| 13022 | 13070 | (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile)) |
| 13023 | 13071 | { |
| 13024 | | if (wanted_type->data.pointer.ptr_len != PtrLenNull || |
| 13025 | | actual_type->data.pointer.child_type->data.array.is_null_terminated) |
| 13072 | ZigType *actual_array_type = actual_type->data.pointer.child_type; |
| 13073 | if (wanted_type->data.pointer.sentinel == nullptr || |
| 13074 | (actual_array_type->data.array.sentinel != nullptr && |
| 13075 | const_values_equal(ira->codegen, wanted_type->data.pointer.sentinel, |
| 13076 | actual_array_type->data.array.sentinel))) |
| 13026 | 13077 | { |
| 13027 | 13078 | if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) |
| 13028 | 13079 | return ira->codegen->invalid_instruction; |
| ... | ... | @@ -14741,7 +14792,6 @@ static bool is_pointer_arithmetic_allowed(ZigType *lhs_type, IrBinOp op) { |
| 14741 | 14792 | case PtrLenSingle: |
| 14742 | 14793 | return lhs_type->data.pointer.child_type->id == ZigTypeIdArray; |
| 14743 | 14794 | case PtrLenUnknown: |
| 14744 | | case PtrLenNull: |
| 14745 | 14795 | case PtrLenC: |
| 14746 | 14796 | return true; |
| 14747 | 14797 | } |
| ... | ... | @@ -15007,7 +15057,7 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15007 | 15057 | if (!op2_val) |
| 15008 | 15058 | return ira->codegen->invalid_instruction; |
| 15009 | 15059 | |
| 15010 | | bool is_null_terminated = false; |
| 15060 | ConstExprValue *sentinel1 = nullptr; |
| 15011 | 15061 | ConstExprValue *op1_array_val; |
| 15012 | 15062 | size_t op1_array_index; |
| 15013 | 15063 | size_t op1_array_end; |
| ... | ... | @@ -15017,16 +15067,17 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15017 | 15067 | op1_array_val = op1_val; |
| 15018 | 15068 | op1_array_index = 0; |
| 15019 | 15069 | op1_array_end = op1_type->data.array.len; |
| 15070 | sentinel1 = op1_type->data.array.sentinel; |
| 15020 | 15071 | } else if (op1_type->id == ZigTypeIdPointer && |
| 15021 | 15072 | op1_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && |
| 15022 | | op1_type->data.pointer.ptr_len == PtrLenNull && |
| 15073 | op1_type->data.pointer.sentinel != nullptr && |
| 15023 | 15074 | op1_val->data.x_ptr.special == ConstPtrSpecialBaseArray) |
| 15024 | 15075 | { |
| 15025 | 15076 | child_type = op1_type->data.pointer.child_type; |
| 15026 | 15077 | op1_array_val = op1_val->data.x_ptr.data.base_array.array_val; |
| 15027 | 15078 | op1_array_index = op1_val->data.x_ptr.data.base_array.elem_index; |
| 15028 | 15079 | op1_array_end = op1_array_val->type->data.array.len; |
| 15029 | | is_null_terminated = true; |
| 15080 | sentinel1 = op1_type->data.pointer.sentinel; |
| 15030 | 15081 | } else if (is_slice(op1_type)) { |
| 15031 | 15082 | ZigType *ptr_type = op1_type->data.structure.fields[slice_ptr_index]->type_entry; |
| 15032 | 15083 | child_type = ptr_type->data.pointer.child_type; |
| ... | ... | @@ -15036,6 +15087,7 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15036 | 15087 | op1_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; |
| 15037 | 15088 | ConstExprValue *len_val = op1_val->data.x_struct.fields[slice_len_index]; |
| 15038 | 15089 | op1_array_end = op1_array_index + bigint_as_usize(&len_val->data.x_bigint); |
| 15090 | sentinel1 = ptr_type->data.pointer.sentinel; |
| 15039 | 15091 | } else if (op1_type->id == ZigTypeIdPointer && op1_type->data.pointer.ptr_len == PtrLenSingle && |
| 15040 | 15092 | op1_type->data.pointer.child_type->id == ZigTypeIdArray) |
| 15041 | 15093 | { |
| ... | ... | @@ -15046,13 +15098,14 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15046 | 15098 | return ira->codegen->invalid_instruction; |
| 15047 | 15099 | op1_array_index = 0; |
| 15048 | 15100 | op1_array_end = array_type->data.array.len; |
| 15049 | | is_null_terminated = is_null_terminated || array_type->data.array.is_null_terminated; |
| 15101 | sentinel1 = array_type->data.array.sentinel; |
| 15050 | 15102 | } else { |
| 15051 | 15103 | ir_add_error(ira, op1, |
| 15052 | 15104 | buf_sprintf("expected array, found '%s'", buf_ptr(&op1->value.type->name))); |
| 15053 | 15105 | return ira->codegen->invalid_instruction; |
| 15054 | 15106 | } |
| 15055 | 15107 | |
| 15108 | ConstExprValue *sentinel2 = nullptr; |
| 15056 | 15109 | ConstExprValue *op2_array_val; |
| 15057 | 15110 | size_t op2_array_index; |
| 15058 | 15111 | size_t op2_array_end; |
| ... | ... | @@ -15062,15 +15115,17 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15062 | 15115 | op2_array_val = op2_val; |
| 15063 | 15116 | op2_array_index = 0; |
| 15064 | 15117 | op2_array_end = op2_array_val->type->data.array.len; |
| 15118 | sentinel2 = op2_type->data.array.sentinel; |
| 15065 | 15119 | } else if (op2_type->id == ZigTypeIdPointer && |
| 15066 | | op2_type->data.pointer.ptr_len == PtrLenNull && |
| 15120 | op2_type->data.pointer.sentinel != nullptr && |
| 15067 | 15121 | op2_val->data.x_ptr.special == ConstPtrSpecialBaseArray) |
| 15068 | 15122 | { |
| 15069 | 15123 | op2_type_valid = op2_type->data.pointer.child_type == child_type; |
| 15070 | 15124 | op2_array_val = op2_val->data.x_ptr.data.base_array.array_val; |
| 15071 | 15125 | op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index; |
| 15072 | 15126 | op2_array_end = op2_array_val->type->data.array.len; |
| 15073 | | is_null_terminated = true; |
| 15127 | |
| 15128 | sentinel2 = op2_type->data.pointer.sentinel; |
| 15074 | 15129 | } else if (is_slice(op2_type)) { |
| 15075 | 15130 | ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index]->type_entry; |
| 15076 | 15131 | op2_type_valid = ptr_type->data.pointer.child_type == child_type; |
| ... | ... | @@ -15080,6 +15135,8 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15080 | 15135 | op2_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; |
| 15081 | 15136 | ConstExprValue *len_val = op2_val->data.x_struct.fields[slice_len_index]; |
| 15082 | 15137 | op2_array_end = op2_array_index + bigint_as_usize(&len_val->data.x_bigint); |
| 15138 | |
| 15139 | sentinel2 = ptr_type->data.pointer.sentinel; |
| 15083 | 15140 | } else if (op2_type->id == ZigTypeIdPointer && op2_type->data.pointer.ptr_len == PtrLenSingle && |
| 15084 | 15141 | op2_type->data.pointer.child_type->id == ZigTypeIdArray) |
| 15085 | 15142 | { |
| ... | ... | @@ -15090,7 +15147,8 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15090 | 15147 | return ira->codegen->invalid_instruction; |
| 15091 | 15148 | op2_array_index = 0; |
| 15092 | 15149 | op2_array_end = array_type->data.array.len; |
| 15093 | | is_null_terminated = is_null_terminated || array_type->data.array.is_null_terminated; |
| 15150 | |
| 15151 | sentinel2 = array_type->data.array.sentinel; |
| 15094 | 15152 | } else { |
| 15095 | 15153 | ir_add_error(ira, op2, |
| 15096 | 15154 | buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op2->value.type->name))); |
| ... | ... | @@ -15103,6 +15161,19 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15103 | 15161 | return ira->codegen->invalid_instruction; |
| 15104 | 15162 | } |
| 15105 | 15163 | |
| 15164 | ConstExprValue *sentinel; |
| 15165 | if (sentinel1 != nullptr && sentinel2 != nullptr) { |
| 15166 | // When there is a sentinel mismatch, no sentinel on the result. The type system |
| 15167 | // will catch this if it is a problem. |
| 15168 | sentinel = const_values_equal(ira->codegen, sentinel1, sentinel2) ? sentinel1 : nullptr; |
| 15169 | } else if (sentinel1 != nullptr) { |
| 15170 | sentinel = sentinel1; |
| 15171 | } else if (sentinel2 != nullptr) { |
| 15172 | sentinel = sentinel2; |
| 15173 | } else { |
| 15174 | sentinel = nullptr; |
| 15175 | } |
| 15176 | |
| 15106 | 15177 | // The type of result is populated in the following if blocks |
| 15107 | 15178 | IrInstruction *result = ir_const(ira, &instruction->base, nullptr); |
| 15108 | 15179 | ConstExprValue *out_val = &result->value; |
| ... | ... | @@ -15110,24 +15181,25 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15110 | 15181 | ConstExprValue *out_array_val; |
| 15111 | 15182 | size_t new_len = (op1_array_end - op1_array_index) + (op2_array_end - op2_array_index); |
| 15112 | 15183 | if (op1_type->id == ZigTypeIdArray || op2_type->id == ZigTypeIdArray) { |
| 15113 | | result->value.type = get_array_type(ira->codegen, child_type, new_len, false); |
| 15184 | result->value.type = get_array_type(ira->codegen, child_type, new_len, sentinel); |
| 15114 | 15185 | |
| 15115 | 15186 | out_array_val = out_val; |
| 15116 | 15187 | } else if (op1_type->id == ZigTypeIdPointer || op2_type->id == ZigTypeIdPointer) { |
| 15117 | 15188 | out_array_val = create_const_vals(1); |
| 15118 | 15189 | out_array_val->special = ConstValSpecialStatic; |
| 15119 | | out_array_val->type = get_array_type(ira->codegen, child_type, new_len, is_null_terminated); |
| 15190 | out_array_val->type = get_array_type(ira->codegen, child_type, new_len, sentinel); |
| 15120 | 15191 | |
| 15121 | 15192 | out_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 15122 | 15193 | out_val->data.x_ptr.data.ref.pointee = out_array_val; |
| 15123 | 15194 | out_val->type = get_pointer_to_type(ira->codegen, out_array_val->type, true); |
| 15124 | 15195 | } else if (is_slice(op1_type) || is_slice(op2_type)) { |
| 15125 | | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, child_type, |
| 15126 | | true, false, PtrLenUnknown, 0, 0, 0, false); |
| 15196 | ZigType *ptr_type = get_pointer_to_type_extra2(ira->codegen, child_type, |
| 15197 | true, false, PtrLenUnknown, 0, 0, 0, false, |
| 15198 | VECTOR_INDEX_NONE, nullptr, sentinel); |
| 15127 | 15199 | result->value.type = get_slice_type(ira->codegen, ptr_type); |
| 15128 | 15200 | out_array_val = create_const_vals(1); |
| 15129 | 15201 | out_array_val->special = ConstValSpecialStatic; |
| 15130 | | out_array_val->type = get_array_type(ira->codegen, child_type, new_len, false); |
| 15202 | out_array_val->type = get_array_type(ira->codegen, child_type, new_len, sentinel); |
| 15131 | 15203 | |
| 15132 | 15204 | out_val->data.x_struct.fields = alloc_const_vals_ptrs(2); |
| 15133 | 15205 | |
| ... | ... | @@ -15141,12 +15213,12 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15141 | 15213 | out_val->data.x_struct.fields[slice_len_index]->special = ConstValSpecialStatic; |
| 15142 | 15214 | bigint_init_unsigned(&out_val->data.x_struct.fields[slice_len_index]->data.x_bigint, new_len); |
| 15143 | 15215 | } else { |
| 15144 | | result->value.type = get_pointer_to_type_extra(ira->codegen, child_type, true, false, PtrLenNull, |
| 15145 | | 0, 0, 0, false); |
| 15216 | result->value.type = get_pointer_to_type_extra2(ira->codegen, child_type, true, false, PtrLenUnknown, |
| 15217 | 0, 0, 0, false, VECTOR_INDEX_NONE, nullptr, sentinel); |
| 15146 | 15218 | |
| 15147 | 15219 | out_array_val = create_const_vals(1); |
| 15148 | 15220 | out_array_val->special = ConstValSpecialStatic; |
| 15149 | | out_array_val->type = get_array_type(ira->codegen, child_type, new_len, false); |
| 15221 | out_array_val->type = get_array_type(ira->codegen, child_type, new_len, sentinel); |
| 15150 | 15222 | out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; |
| 15151 | 15223 | out_val->data.x_ptr.data.base_array.array_val = out_array_val; |
| 15152 | 15224 | out_val->data.x_ptr.data.base_array.elem_index = 0; |
| ... | ... | @@ -15159,26 +15231,36 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15159 | 15231 | return result; |
| 15160 | 15232 | } |
| 15161 | 15233 | |
| 15162 | | out_array_val->data.x_array.data.s_none.elements = create_const_vals(new_len); |
| 15234 | uint64_t full_len = new_len + ((sentinel != nullptr) ? 1 : 0); |
| 15235 | out_array_val->data.x_array.data.s_none.elements = create_const_vals(full_len); |
| 15163 | 15236 | // TODO handle the buf case here for an optimization |
| 15164 | 15237 | expand_undef_array(ira->codegen, op1_array_val); |
| 15165 | 15238 | expand_undef_array(ira->codegen, op2_array_val); |
| 15166 | 15239 | |
| 15167 | 15240 | size_t next_index = 0; |
| 15168 | 15241 | for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { |
| 15169 | | copy_const_val(&out_array_val->data.x_array.data.s_none.elements[next_index], |
| 15170 | | &op1_array_val->data.x_array.data.s_none.elements[i], true); |
| 15242 | ConstExprValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index]; |
| 15243 | copy_const_val(elem_dest_val, &op1_array_val->data.x_array.data.s_none.elements[i], false); |
| 15244 | elem_dest_val->parent.id = ConstParentIdArray; |
| 15245 | elem_dest_val->parent.data.p_array.array_val = out_array_val; |
| 15246 | elem_dest_val->parent.data.p_array.elem_index = next_index; |
| 15171 | 15247 | } |
| 15172 | 15248 | for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) { |
| 15173 | | copy_const_val(&out_array_val->data.x_array.data.s_none.elements[next_index], |
| 15174 | | &op2_array_val->data.x_array.data.s_none.elements[i], true); |
| 15175 | | } |
| 15176 | | if (next_index < new_len) { |
| 15177 | | ConstExprValue *null_byte = &out_array_val->data.x_array.data.s_none.elements[next_index]; |
| 15178 | | init_const_unsigned_negative(null_byte, child_type, 0, false); |
| 15249 | ConstExprValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index]; |
| 15250 | copy_const_val(elem_dest_val, &op2_array_val->data.x_array.data.s_none.elements[i], false); |
| 15251 | elem_dest_val->parent.id = ConstParentIdArray; |
| 15252 | elem_dest_val->parent.data.p_array.array_val = out_array_val; |
| 15253 | elem_dest_val->parent.data.p_array.elem_index = next_index; |
| 15254 | } |
| 15255 | if (next_index < full_len) { |
| 15256 | ConstExprValue *elem_dest_val = &out_array_val->data.x_array.data.s_none.elements[next_index]; |
| 15257 | copy_const_val(elem_dest_val, sentinel, false); |
| 15258 | elem_dest_val->parent.id = ConstParentIdArray; |
| 15259 | elem_dest_val->parent.data.p_array.array_val = out_array_val; |
| 15260 | elem_dest_val->parent.data.p_array.elem_index = next_index; |
| 15179 | 15261 | next_index += 1; |
| 15180 | 15262 | } |
| 15181 | | assert(next_index == new_len); |
| 15263 | assert(next_index == full_len); |
| 15182 | 15264 | |
| 15183 | 15265 | return result; |
| 15184 | 15266 | } |
| ... | ... | @@ -15230,7 +15312,7 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * |
| 15230 | 15312 | |
| 15231 | 15313 | ZigType *child_type = array_type->data.array.child_type; |
| 15232 | 15314 | ZigType *result_array_type = get_array_type(ira->codegen, child_type, new_array_len, |
| 15233 | | array_type->data.array.is_null_terminated); |
| 15315 | array_type->data.array.sentinel); |
| 15234 | 15316 | |
| 15235 | 15317 | IrInstruction *array_result; |
| 15236 | 15318 | if (array_val->special == ConstValSpecialUndef || array_val->data.x_array.special == ConstArraySpecialUndef) { |
| ... | ... | @@ -15250,7 +15332,7 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * |
| 15250 | 15332 | |
| 15251 | 15333 | // TODO optimize the buf case |
| 15252 | 15334 | expand_undef_array(ira->codegen, array_val); |
| 15253 | | size_t extra_null_term = array_type->data.array.is_null_terminated ? 1 : 0; |
| 15335 | size_t extra_null_term = (array_type->data.array.sentinel != nullptr) ? 1 : 0; |
| 15254 | 15336 | out_val->data.x_array.data.s_none.elements = create_const_vals(new_array_len + extra_null_term); |
| 15255 | 15337 | |
| 15256 | 15338 | uint64_t i = 0; |
| ... | ... | @@ -15266,10 +15348,9 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * |
| 15266 | 15348 | } |
| 15267 | 15349 | assert(i == new_array_len); |
| 15268 | 15350 | |
| 15269 | | if (array_type->data.array.is_null_terminated) { |
| 15270 | | ConstExprValue *null_value = get_null_value(array_type->data.array.child_type); |
| 15351 | if (array_type->data.array.sentinel != nullptr) { |
| 15271 | 15352 | ConstExprValue *elem_dest_val = &out_val->data.x_array.data.s_none.elements[i]; |
| 15272 | | copy_const_val(elem_dest_val, null_value, false); |
| 15353 | copy_const_val(elem_dest_val, array_type->data.array.sentinel, false); |
| 15273 | 15354 | elem_dest_val->parent.id = ConstParentIdArray; |
| 15274 | 15355 | elem_dest_val->parent.data.p_array.array_val = out_val; |
| 15275 | 15356 | elem_dest_val->parent.data.p_array.elem_index = i; |
| ... | ... | @@ -17565,7 +17646,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source |
| 17565 | 17646 | size_t dst_size = type_size(codegen, out_val->type); |
| 17566 | 17647 | |
| 17567 | 17648 | if (dst_size <= src_size) { |
| 17568 | | if (src_size == dst_size && types_have_same_zig_comptime_repr(out_val->type, pointee->type)) { |
| 17649 | if (src_size == dst_size && types_have_same_zig_comptime_repr(codegen, out_val->type, pointee->type)) { |
| 17569 | 17650 | copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut != ConstPtrMutComptimeVar); |
| 17570 | 17651 | return ErrorNone; |
| 17571 | 17652 | } |
| ... | ... | @@ -18316,11 +18397,11 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 18316 | 18397 | uint64_t index = bigint_as_u64(&casted_elem_index->value.data.x_bigint); |
| 18317 | 18398 | if (array_type->id == ZigTypeIdArray) { |
| 18318 | 18399 | uint64_t array_len = array_type->data.array.len; |
| 18319 | | if (index == array_len && array_type->data.array.is_null_terminated) { |
| 18400 | if (index == array_len && array_type->data.array.sentinel != nullptr) { |
| 18320 | 18401 | ZigType *elem_type = array_type->data.array.child_type; |
| 18321 | | IrInstruction *null_element = ir_const(ira, &elem_ptr_instruction->base, elem_type); |
| 18322 | | null_element->value = *get_null_value(elem_type); |
| 18323 | | return ir_get_ref(ira, &elem_ptr_instruction->base, null_element, true, false); |
| 18402 | IrInstruction *sentinel_elem = ir_const(ira, &elem_ptr_instruction->base, elem_type); |
| 18403 | copy_const_val(&sentinel_elem->value, array_type->data.array.sentinel, false); |
| 18404 | return ir_get_ref(ira, &elem_ptr_instruction->base, sentinel_elem, true, false); |
| 18324 | 18405 | } |
| 18325 | 18406 | if (index >= array_len) { |
| 18326 | 18407 | ir_add_error_node(ira, elem_ptr_instruction->base.source_node, |
| ... | ... | @@ -18337,7 +18418,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 18337 | 18418 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, |
| 18338 | 18419 | elem_ptr_instruction->ptr_len, |
| 18339 | 18420 | get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, (uint32_t)index, |
| 18340 | | nullptr); |
| 18421 | nullptr, nullptr); |
| 18341 | 18422 | } else if (return_type->data.pointer.explicit_alignment != 0) { |
| 18342 | 18423 | // figure out the largest alignment possible |
| 18343 | 18424 | |
| ... | ... | @@ -18457,7 +18538,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 18457 | 18538 | new_index = offset + index; |
| 18458 | 18539 | ZigType *array_type = array_ptr_val->data.x_ptr.data.base_array.array_val->type; |
| 18459 | 18540 | mem_size = array_type->data.array.len; |
| 18460 | | if (array_type->data.array.is_null_terminated) { |
| 18541 | if (array_type->data.array.sentinel != nullptr) { |
| 18461 | 18542 | mem_size += 1; |
| 18462 | 18543 | } |
| 18463 | 18544 | old_size = mem_size - offset; |
| ... | ... | @@ -18579,7 +18660,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 18579 | 18660 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, |
| 18580 | 18661 | elem_ptr_instruction->ptr_len, |
| 18581 | 18662 | get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, VECTOR_INDEX_RUNTIME, |
| 18582 | | nullptr); |
| 18663 | nullptr, nullptr); |
| 18583 | 18664 | } else { |
| 18584 | 18665 | // runtime known element index |
| 18585 | 18666 | switch (type_requires_comptime(ira->codegen, return_type)) { |
| ... | ... | @@ -18783,7 +18864,7 @@ static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_n |
| 18783 | 18864 | ZigType *elem_type = ira->codegen->builtin_types.entry_var; |
| 18784 | 18865 | ZigType *field_ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type, |
| 18785 | 18866 | container_ptr_type->data.pointer.is_const, container_ptr_type->data.pointer.is_volatile, |
| 18786 | | PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, inferred_struct_field); |
| 18867 | PtrLenSingle, 0, 0, 0, false, VECTOR_INDEX_NONE, inferred_struct_field, nullptr); |
| 18787 | 18868 | |
| 18788 | 18869 | if (instr_is_comptime(container_ptr)) { |
| 18789 | 18870 | IrInstruction *result = ir_const(ira, source_instr, field_ptr_type); |
| ... | ... | @@ -19565,6 +19646,12 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| 19565 | 19646 | return ira->codegen->invalid_instruction; |
| 19566 | 19647 | } |
| 19567 | 19648 | |
| 19649 | if (slice_type_instruction->sentinel != nullptr) { |
| 19650 | lazy_slice_type->sentinel = slice_type_instruction->sentinel->child; |
| 19651 | if (ir_resolve_const(ira, lazy_slice_type->sentinel, LazyOk) == nullptr) |
| 19652 | return ira->codegen->invalid_instruction; |
| 19653 | } |
| 19654 | |
| 19568 | 19655 | lazy_slice_type->elem_type = slice_type_instruction->child_type->child; |
| 19569 | 19656 | if (ir_resolve_type_lazy(ira, lazy_slice_type->elem_type) == nullptr) |
| 19570 | 19657 | return ira->codegen->invalid_instruction; |
| ... | ... | @@ -19572,7 +19659,6 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| 19572 | 19659 | lazy_slice_type->is_const = slice_type_instruction->is_const; |
| 19573 | 19660 | lazy_slice_type->is_volatile = slice_type_instruction->is_volatile; |
| 19574 | 19661 | lazy_slice_type->is_allowzero = slice_type_instruction->is_allow_zero; |
| 19575 | | lazy_slice_type->is_null_terminated = slice_type_instruction->is_null_terminated; |
| 19576 | 19662 | |
| 19577 | 19663 | return result; |
| 19578 | 19664 | } |
| ... | ... | @@ -19647,6 +19733,22 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, |
| 19647 | 19733 | ZigType *child_type = ir_resolve_type(ira, child_type_value); |
| 19648 | 19734 | if (type_is_invalid(child_type)) |
| 19649 | 19735 | return ira->codegen->invalid_instruction; |
| 19736 | |
| 19737 | ConstExprValue *sentinel_val; |
| 19738 | if (array_type_instruction->sentinel != nullptr) { |
| 19739 | IrInstruction *uncasted_sentinel = array_type_instruction->sentinel->child; |
| 19740 | if (type_is_invalid(uncasted_sentinel->value.type)) |
| 19741 | return ira->codegen->invalid_instruction; |
| 19742 | IrInstruction *sentinel = ir_implicit_cast(ira, uncasted_sentinel, child_type); |
| 19743 | if (type_is_invalid(sentinel->value.type)) |
| 19744 | return ira->codegen->invalid_instruction; |
| 19745 | sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); |
| 19746 | if (sentinel_val == nullptr) |
| 19747 | return ira->codegen->invalid_instruction; |
| 19748 | } else { |
| 19749 | sentinel_val = nullptr; |
| 19750 | } |
| 19751 | |
| 19650 | 19752 | switch (child_type->id) { |
| 19651 | 19753 | case ZigTypeIdInvalid: // handled above |
| 19652 | 19754 | zig_unreachable(); |
| ... | ... | @@ -19682,8 +19784,7 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, |
| 19682 | 19784 | { |
| 19683 | 19785 | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) |
| 19684 | 19786 | return ira->codegen->invalid_instruction; |
| 19685 | | ZigType *result_type = get_array_type(ira->codegen, child_type, size, |
| 19686 | | array_type_instruction->is_null_terminated); |
| 19787 | ZigType *result_type = get_array_type(ira->codegen, child_type, size, sentinel_val); |
| 19687 | 19788 | return ir_const_type(ira, &array_type_instruction->base, result_type); |
| 19688 | 19789 | } |
| 19689 | 19790 | } |
| ... | ... | @@ -19802,7 +19903,7 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr |
| 19802 | 19903 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, |
| 19803 | 19904 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0, false); |
| 19804 | 19905 | |
| 19805 | | bool same_comptime_repr = types_have_same_zig_comptime_repr(child_type, type_entry); |
| 19906 | bool same_comptime_repr = types_have_same_zig_comptime_repr(ira->codegen, child_type, type_entry); |
| 19806 | 19907 | |
| 19807 | 19908 | if (instr_is_comptime(base_ptr)) { |
| 19808 | 19909 | ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); |
| ... | ... | @@ -20759,7 +20860,7 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, |
| 20759 | 20860 | if (container_type->id == ZigTypeIdArray) { |
| 20760 | 20861 | ZigType *child_type = container_type->data.array.child_type; |
| 20761 | 20862 | if (container_type->data.array.len != elem_count) { |
| 20762 | | ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count, false); |
| 20863 | ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count, nullptr); |
| 20763 | 20864 | |
| 20764 | 20865 | ir_add_error(ira, &instruction->base, |
| 20765 | 20866 | buf_sprintf("expected %s literal, found %s literal", |
| ... | ... | @@ -21246,7 +21347,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr |
| 21246 | 21347 | |
| 21247 | 21348 | ConstExprValue *declaration_array = create_const_vals(1); |
| 21248 | 21349 | declaration_array->special = ConstValSpecialStatic; |
| 21249 | | declaration_array->type = get_array_type(ira->codegen, type_info_declaration_type, declaration_count, false); |
| 21350 | declaration_array->type = get_array_type(ira->codegen, type_info_declaration_type, declaration_count, nullptr); |
| 21250 | 21351 | declaration_array->data.x_array.special = ConstArraySpecialNone; |
| 21251 | 21352 | declaration_array->data.x_array.data.s_none.elements = create_const_vals(declaration_count); |
| 21252 | 21353 | init_const_slice(ira->codegen, out_val, declaration_array, 0, declaration_count, false); |
| ... | ... | @@ -21391,7 +21492,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr |
| 21391 | 21492 | ConstExprValue *fn_arg_name_array = create_const_vals(1); |
| 21392 | 21493 | fn_arg_name_array->special = ConstValSpecialStatic; |
| 21393 | 21494 | fn_arg_name_array->type = get_array_type(ira->codegen, |
| 21394 | | get_slice_type(ira->codegen, u8_ptr), fn_arg_count, false); |
| 21495 | get_slice_type(ira->codegen, u8_ptr), fn_arg_count, nullptr); |
| 21395 | 21496 | fn_arg_name_array->data.x_array.special = ConstArraySpecialNone; |
| 21396 | 21497 | fn_arg_name_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); |
| 21397 | 21498 | |
| ... | ... | @@ -21446,7 +21547,6 @@ static BuiltinPtrSize ptr_len_to_size_enum_index(PtrLen ptr_len) { |
| 21446 | 21547 | case PtrLenSingle: |
| 21447 | 21548 | return BuiltinPtrSizeOne; |
| 21448 | 21549 | case PtrLenUnknown: |
| 21449 | | case PtrLenNull: |
| 21450 | 21550 | return BuiltinPtrSizeMany; |
| 21451 | 21551 | case PtrLenC: |
| 21452 | 21552 | return BuiltinPtrSizeC; |
| ... | ... | @@ -21527,11 +21627,21 @@ static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_ty |
| 21527 | 21627 | fields[5]->special = ConstValSpecialStatic; |
| 21528 | 21628 | fields[5]->type = ira->codegen->builtin_types.entry_bool; |
| 21529 | 21629 | fields[5]->data.x_bool = attrs_type->data.pointer.allow_zero; |
| 21530 | | // is_null_terminated: bool |
| 21531 | | ensure_field_index(result->type, "is_null_terminated", 6); |
| 21630 | // sentinel: ?*const c_void |
| 21631 | ZigType *ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_c_void, true); |
| 21632 | ensure_field_index(result->type, "sentinel", 6); |
| 21532 | 21633 | fields[6]->special = ConstValSpecialStatic; |
| 21533 | | fields[6]->type = ira->codegen->builtin_types.entry_bool; |
| 21534 | | fields[6]->data.x_bool = attrs_type->data.pointer.ptr_len == PtrLenNull; |
| 21634 | fields[6]->type = get_optional_type(ira->codegen, ptr_type); |
| 21635 | if (attrs_type->data.pointer.sentinel == nullptr) { |
| 21636 | fields[6]->data.x_optional = nullptr; |
| 21637 | } else { |
| 21638 | ConstExprValue *ptr_val = create_const_vals(1); |
| 21639 | fields[6]->data.x_optional = ptr_val; |
| 21640 | ptr_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 21641 | ptr_val->data.x_ptr.mut = ConstPtrMutComptimeConst; |
| 21642 | ptr_val->data.x_ptr.data.ref.pointee = create_const_vals(1); |
| 21643 | copy_const_val(ptr_val->data.x_ptr.data.ref.pointee, attrs_type->data.pointer.sentinel, false); |
| 21644 | } |
| 21535 | 21645 | |
| 21536 | 21646 | return result; |
| 21537 | 21647 | }; |
| ... | ... | @@ -21652,11 +21762,22 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 21652 | 21762 | fields[1]->special = ConstValSpecialStatic; |
| 21653 | 21763 | fields[1]->type = ira->codegen->builtin_types.entry_type; |
| 21654 | 21764 | fields[1]->data.x_type = type_entry->data.array.child_type; |
| 21655 | | // is_null_terminated: bool |
| 21656 | | ensure_field_index(result->type, "is_null_terminated", 2); |
| 21765 | // sentinel: ?*const c_void |
| 21657 | 21766 | fields[2]->special = ConstValSpecialStatic; |
| 21658 | | fields[2]->type = ira->codegen->builtin_types.entry_bool; |
| 21659 | | fields[2]->data.x_bool = type_entry->data.array.is_null_terminated; |
| 21767 | ZigType *ptr_type = get_pointer_to_type(ira->codegen, |
| 21768 | ira->codegen->builtin_types.entry_c_void, true); |
| 21769 | fields[2]->type = get_optional_type(ira->codegen, ptr_type); |
| 21770 | if (type_entry->data.array.sentinel == nullptr) { |
| 21771 | fields[2]->data.x_optional = nullptr; |
| 21772 | } else { |
| 21773 | ConstExprValue *ptr_val = create_const_vals(1); |
| 21774 | fields[2]->data.x_optional = ptr_val; |
| 21775 | ptr_val->type = ptr_type; |
| 21776 | ptr_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 21777 | ptr_val->data.x_ptr.mut = ConstPtrMutComptimeConst; |
| 21778 | ptr_val->data.x_ptr.data.ref.pointee = create_const_vals(1); |
| 21779 | copy_const_val(ptr_val->data.x_ptr.data.ref.pointee, type_entry->data.array.sentinel, false); |
| 21780 | } |
| 21660 | 21781 | |
| 21661 | 21782 | break; |
| 21662 | 21783 | } |
| ... | ... | @@ -21744,7 +21865,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 21744 | 21865 | |
| 21745 | 21866 | ConstExprValue *enum_field_array = create_const_vals(1); |
| 21746 | 21867 | enum_field_array->special = ConstValSpecialStatic; |
| 21747 | | enum_field_array->type = get_array_type(ira->codegen, type_info_enum_field_type, enum_field_count, false); |
| 21868 | enum_field_array->type = get_array_type(ira->codegen, type_info_enum_field_type, enum_field_count, nullptr); |
| 21748 | 21869 | enum_field_array->data.x_array.special = ConstArraySpecialNone; |
| 21749 | 21870 | enum_field_array->data.x_array.data.s_none.elements = create_const_vals(enum_field_count); |
| 21750 | 21871 | |
| ... | ... | @@ -21792,7 +21913,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 21792 | 21913 | uint32_t error_count = type_entry->data.error_set.err_count; |
| 21793 | 21914 | ConstExprValue *error_array = create_const_vals(1); |
| 21794 | 21915 | error_array->special = ConstValSpecialStatic; |
| 21795 | | error_array->type = get_array_type(ira->codegen, type_info_error_type, error_count, false); |
| 21916 | error_array->type = get_array_type(ira->codegen, type_info_error_type, error_count, nullptr); |
| 21796 | 21917 | error_array->data.x_array.special = ConstArraySpecialNone; |
| 21797 | 21918 | error_array->data.x_array.data.s_none.elements = create_const_vals(error_count); |
| 21798 | 21919 | |
| ... | ... | @@ -21888,7 +22009,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 21888 | 22009 | |
| 21889 | 22010 | ConstExprValue *union_field_array = create_const_vals(1); |
| 21890 | 22011 | union_field_array->special = ConstValSpecialStatic; |
| 21891 | | union_field_array->type = get_array_type(ira->codegen, type_info_union_field_type, union_field_count, false); |
| 22012 | union_field_array->type = get_array_type(ira->codegen, type_info_union_field_type, union_field_count, nullptr); |
| 21892 | 22013 | union_field_array->data.x_array.special = ConstArraySpecialNone; |
| 21893 | 22014 | union_field_array->data.x_array.data.s_none.elements = create_const_vals(union_field_count); |
| 21894 | 22015 | |
| ... | ... | @@ -21968,7 +22089,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 21968 | 22089 | |
| 21969 | 22090 | ConstExprValue *struct_field_array = create_const_vals(1); |
| 21970 | 22091 | struct_field_array->special = ConstValSpecialStatic; |
| 21971 | | struct_field_array->type = get_array_type(ira->codegen, type_info_struct_field_type, struct_field_count, false); |
| 22092 | struct_field_array->type = get_array_type(ira->codegen, type_info_struct_field_type, struct_field_count, nullptr); |
| 21972 | 22093 | struct_field_array->data.x_array.special = ConstArraySpecialNone; |
| 21973 | 22094 | struct_field_array->data.x_array.data.s_none.elements = create_const_vals(struct_field_count); |
| 21974 | 22095 | |
| ... | ... | @@ -22071,7 +22192,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 22071 | 22192 | |
| 22072 | 22193 | ConstExprValue *fn_arg_array = create_const_vals(1); |
| 22073 | 22194 | fn_arg_array->special = ConstValSpecialStatic; |
| 22074 | | fn_arg_array->type = get_array_type(ira->codegen, type_info_fn_arg_type, fn_arg_count, false); |
| 22195 | fn_arg_array->type = get_array_type(ira->codegen, type_info_fn_arg_type, fn_arg_count, nullptr); |
| 22075 | 22196 | fn_arg_array->data.x_array.special = ConstArraySpecialNone; |
| 22076 | 22197 | fn_arg_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); |
| 22077 | 22198 | |
| ... | ... | @@ -22169,6 +22290,17 @@ static ConstExprValue *get_const_field(IrAnalyze *ira, ConstExprValue *struct_va |
| 22169 | 22290 | return struct_value->data.x_struct.fields[field_index]; |
| 22170 | 22291 | } |
| 22171 | 22292 | |
| 22293 | static ConstExprValue *get_const_field_variant(IrAnalyze *ira, ConstExprValue *struct_value, |
| 22294 | const char *name, size_t field_index) |
| 22295 | { |
| 22296 | ConstExprValue *field_val = get_const_field(ira, struct_value, name, field_index); |
| 22297 | assert(field_val->type->id == ZigTypeIdOptional); |
| 22298 | ConstExprValue *opt_val = field_val->data.x_optional; |
| 22299 | if (opt_val == nullptr) return nullptr; |
| 22300 | assert(opt_val->type->id == ZigTypeIdPointer); |
| 22301 | return const_ptr_pointee_unchecked(ira->codegen, opt_val); |
| 22302 | } |
| 22303 | |
| 22172 | 22304 | static bool get_const_field_bool(IrAnalyze *ira, ConstExprValue *struct_value, const char *name, size_t field_index) |
| 22173 | 22305 | { |
| 22174 | 22306 | ConstExprValue *value = get_const_field(ira, struct_value, name, field_index); |
| ... | ... | @@ -22232,7 +22364,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi |
| 22232 | 22364 | assert(size_value->type == ir_type_info_get_type(ira, "Size", type_info_pointer_type)); |
| 22233 | 22365 | BuiltinPtrSize size_enum_index = (BuiltinPtrSize)bigint_as_u32(&size_value->data.x_enum_tag); |
| 22234 | 22366 | PtrLen ptr_len = size_enum_index_to_ptr_len(size_enum_index); |
| 22235 | | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, |
| 22367 | ZigType *ptr_type = get_pointer_to_type_extra2(ira->codegen, |
| 22236 | 22368 | get_const_field_meta_type(ira, payload, "child", 4), |
| 22237 | 22369 | get_const_field_bool(ira, payload, "is_const", 1), |
| 22238 | 22370 | get_const_field_bool(ira, payload, "is_volatile", 2), |
| ... | ... | @@ -22240,7 +22372,10 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi |
| 22240 | 22372 | bigint_as_u32(get_const_field_lit_int(ira, payload, "alignment", 3)), |
| 22241 | 22373 | 0, // bit_offset_in_host |
| 22242 | 22374 | 0, // host_int_bytes |
| 22243 | | get_const_field_bool(ira, payload, "is_allowzero", 5) |
| 22375 | get_const_field_bool(ira, payload, "is_allowzero", 5), |
| 22376 | VECTOR_INDEX_NONE, |
| 22377 | nullptr, |
| 22378 | get_const_field_variant(ira, payload, "sentinel", 6) |
| 22244 | 22379 | ); |
| 22245 | 22380 | if (size_enum_index != 2) |
| 22246 | 22381 | return ptr_type; |
| ... | ... | @@ -22252,7 +22387,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi |
| 22252 | 22387 | return get_array_type(ira->codegen, |
| 22253 | 22388 | get_const_field_meta_type(ira, payload, "child", 1), |
| 22254 | 22389 | bigint_as_u64(get_const_field_lit_int(ira, payload, "len", 0)), |
| 22255 | | get_const_field_bool(ira, payload, "is_null_terminated", 2) |
| 22390 | get_const_field_variant(ira, payload, "sentinel", 2) |
| 22256 | 22391 | ); |
| 22257 | 22392 | case ZigTypeIdComptimeFloat: |
| 22258 | 22393 | return ira->codegen->builtin_types.entry_num_lit_float; |
| ... | ... | @@ -22635,7 +22770,7 @@ static IrInstruction *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstru |
| 22635 | 22770 | } |
| 22636 | 22771 | |
| 22637 | 22772 | ZigType *result_type = get_array_type(ira->codegen, |
| 22638 | | ira->codegen->builtin_types.entry_u8, buf_len(file_contents), false); |
| 22773 | ira->codegen->builtin_types.entry_u8, buf_len(file_contents), nullptr); |
| 22639 | 22774 | IrInstruction *result = ir_const(ira, &instruction->base, result_type); |
| 22640 | 22775 | init_const_str_lit(ira->codegen, &result->value, file_contents); |
| 22641 | 22776 | return result; |
| ... | ... | @@ -25858,6 +25993,12 @@ static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruct |
| 25858 | 25993 | result->value.data.x_lazy = &lazy_ptr_type->base; |
| 25859 | 25994 | lazy_ptr_type->base.id = LazyValueIdPtrType; |
| 25860 | 25995 | |
| 25996 | if (instruction->sentinel != nullptr) { |
| 25997 | lazy_ptr_type->sentinel = instruction->sentinel->child; |
| 25998 | if (ir_resolve_const(ira, lazy_ptr_type->sentinel, LazyOk) == nullptr) |
| 25999 | return ira->codegen->invalid_instruction; |
| 26000 | } |
| 26001 | |
| 25861 | 26002 | lazy_ptr_type->elem_type = instruction->child_type->child; |
| 25862 | 26003 | if (ir_resolve_type_lazy(ira, lazy_ptr_type->elem_type) == nullptr) |
| 25863 | 26004 | return ira->codegen->invalid_instruction; |
| ... | ... | @@ -27804,6 +27945,20 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ConstExprValue *val) { |
| 27804 | 27945 | if (type_is_invalid(elem_type)) |
| 27805 | 27946 | return ErrorSemanticAnalyzeFail; |
| 27806 | 27947 | |
| 27948 | ConstExprValue *sentinel_val; |
| 27949 | if (lazy_slice_type->sentinel != nullptr) { |
| 27950 | if (type_is_invalid(lazy_slice_type->sentinel->value.type)) |
| 27951 | return ErrorSemanticAnalyzeFail; |
| 27952 | IrInstruction *sentinel = ir_implicit_cast(ira, lazy_slice_type->sentinel, elem_type); |
| 27953 | if (type_is_invalid(sentinel->value.type)) |
| 27954 | return ErrorSemanticAnalyzeFail; |
| 27955 | sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); |
| 27956 | if (sentinel_val == nullptr) |
| 27957 | return ErrorSemanticAnalyzeFail; |
| 27958 | } else { |
| 27959 | sentinel_val = nullptr; |
| 27960 | } |
| 27961 | |
| 27807 | 27962 | uint32_t align_bytes = 0; |
| 27808 | 27963 | if (lazy_slice_type->align_inst != nullptr) { |
| 27809 | 27964 | if (!ir_resolve_align(ira, lazy_slice_type->align_inst, elem_type, &align_bytes)) |
| ... | ... | @@ -27849,11 +28004,12 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ConstExprValue *val) { |
| 27849 | 28004 | ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown; |
| 27850 | 28005 | if ((err = type_resolve(ira->codegen, elem_type, needed_status))) |
| 27851 | 28006 | return err; |
| 27852 | | ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, elem_type, |
| 28007 | ZigType *slice_ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type, |
| 27853 | 28008 | lazy_slice_type->is_const, lazy_slice_type->is_volatile, |
| 27854 | | lazy_slice_type->is_null_terminated ? PtrLenNull : PtrLenUnknown, |
| 28009 | PtrLenUnknown, |
| 27855 | 28010 | align_bytes, |
| 27856 | | 0, 0, lazy_slice_type->is_allowzero); |
| 28011 | 0, 0, lazy_slice_type->is_allowzero, |
| 28012 | VECTOR_INDEX_NONE, nullptr, sentinel_val); |
| 27857 | 28013 | val->special = ConstValSpecialStatic; |
| 27858 | 28014 | assert(val->type->id == ZigTypeIdMetaType); |
| 27859 | 28015 | val->data.x_type = get_slice_type(ira->codegen, slice_ptr_type); |
| ... | ... | @@ -27867,6 +28023,20 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ConstExprValue *val) { |
| 27867 | 28023 | if (type_is_invalid(elem_type)) |
| 27868 | 28024 | return ErrorSemanticAnalyzeFail; |
| 27869 | 28025 | |
| 28026 | ConstExprValue *sentinel_val; |
| 28027 | if (lazy_ptr_type->sentinel != nullptr) { |
| 28028 | if (type_is_invalid(lazy_ptr_type->sentinel->value.type)) |
| 28029 | return ErrorSemanticAnalyzeFail; |
| 28030 | IrInstruction *sentinel = ir_implicit_cast(ira, lazy_ptr_type->sentinel, elem_type); |
| 28031 | if (type_is_invalid(sentinel->value.type)) |
| 28032 | return ErrorSemanticAnalyzeFail; |
| 28033 | sentinel_val = ir_resolve_const(ira, sentinel, UndefBad); |
| 28034 | if (sentinel_val == nullptr) |
| 28035 | return ErrorSemanticAnalyzeFail; |
| 28036 | } else { |
| 28037 | sentinel_val = nullptr; |
| 28038 | } |
| 28039 | |
| 27870 | 28040 | uint32_t align_bytes = 0; |
| 27871 | 28041 | if (lazy_ptr_type->align_inst != nullptr) { |
| 27872 | 28042 | if (!ir_resolve_align(ira, lazy_ptr_type->align_inst, elem_type, &align_bytes)) |
| ... | ... | @@ -27909,10 +28079,10 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ConstExprValue *val) { |
| 27909 | 28079 | } |
| 27910 | 28080 | bool allow_zero = lazy_ptr_type->is_allowzero || lazy_ptr_type->ptr_len == PtrLenC; |
| 27911 | 28081 | assert(val->type->id == ZigTypeIdMetaType); |
| 27912 | | val->data.x_type = get_pointer_to_type_extra(ira->codegen, elem_type, |
| 28082 | val->data.x_type = get_pointer_to_type_extra2(ira->codegen, elem_type, |
| 27913 | 28083 | lazy_ptr_type->is_const, lazy_ptr_type->is_volatile, lazy_ptr_type->ptr_len, align_bytes, |
| 27914 | 28084 | lazy_ptr_type->bit_offset_in_host, lazy_ptr_type->host_int_bytes, |
| 27915 | | allow_zero); |
| 28085 | allow_zero, VECTOR_INDEX_NONE, nullptr, sentinel_val); |
| 27916 | 28086 | val->special = ConstValSpecialStatic; |
| 27917 | 28087 | return ErrorNone; |
| 27918 | 28088 | } |