| ... | @@ -67,9 +67,10 @@ enum ConstCastResultId { | ... | @@ -67,9 +67,10 @@ enum ConstCastResultId { |
| 67 | ConstCastResultIdAsyncAllocatorType, | 67 | ConstCastResultIdAsyncAllocatorType, |
| 68 | ConstCastResultIdBadAllowsZero, | 68 | ConstCastResultIdBadAllowsZero, |
| 69 | ConstCastResultIdArrayChild, | 69 | ConstCastResultIdArrayChild, |
| 70 | ConstCastResultIdBadNullTermArrays, | 70 | ConstCastResultIdSentinelArrays, |
| 71 | ConstCastResultIdPtrLens, | 71 | ConstCastResultIdPtrLens, |
| 72 | ConstCastResultIdCV, | 72 | ConstCastResultIdCV, |
| | 73 | ConstCastResultIdPtrSentinel, |
| 73 | }; | 74 | }; |
| 74 | | 75 | |
| 75 | struct ConstCastOnly; | 76 | struct ConstCastOnly; |
| ... | @@ -94,8 +95,8 @@ struct ConstCastTypeMismatch; | ... | @@ -94,8 +95,8 @@ struct ConstCastTypeMismatch; |
| 94 | struct ConstCastArrayMismatch; | 95 | struct ConstCastArrayMismatch; |
| 95 | struct ConstCastBadAllowsZero; | 96 | struct ConstCastBadAllowsZero; |
| 96 | struct ConstCastBadNullTermArrays; | 97 | struct ConstCastBadNullTermArrays; |
| 97 | struct ConstCastBadPtrLens; | | |
| 98 | struct ConstCastBadCV; | 98 | struct ConstCastBadCV; |
| | 99 | struct ConstCastPtrSentinel; |
| 99 | | 100 | |
| 100 | struct ConstCastOnly { | 101 | struct ConstCastOnly { |
| 101 | ConstCastResultId id; | 102 | ConstCastResultId id; |
| ... | @@ -113,9 +114,9 @@ struct ConstCastOnly { | ... | @@ -113,9 +114,9 @@ struct ConstCastOnly { |
| 113 | ConstCastArg fn_arg; | 114 | ConstCastArg fn_arg; |
| 114 | ConstCastArgNoAlias arg_no_alias; | 115 | ConstCastArgNoAlias arg_no_alias; |
| 115 | ConstCastBadAllowsZero *bad_allows_zero; | 116 | ConstCastBadAllowsZero *bad_allows_zero; |
| 116 | ConstCastBadNullTermArrays *bad_null_term_arrays; | 117 | ConstCastBadNullTermArrays *sentinel_arrays; |
| 117 | ConstCastBadPtrLens *bad_ptr_lens; | | |
| 118 | ConstCastBadCV *bad_cv; | 118 | ConstCastBadCV *bad_cv; |
| | 119 | ConstCastPtrSentinel *bad_ptr_sentinel; |
| 119 | } data; | 120 | } data; |
| 120 | }; | 121 | }; |
| 121 | | 122 | |
| ... | @@ -175,14 +176,13 @@ struct ConstCastBadNullTermArrays { | ... | @@ -175,14 +176,13 @@ struct ConstCastBadNullTermArrays { |
| 175 | ZigType *actual_type; | 176 | ZigType *actual_type; |
| 176 | }; | 177 | }; |
| 177 | | 178 | |
| 178 | struct ConstCastBadPtrLens { | 179 | struct ConstCastBadCV { |
| 179 | ZigType *wanted_type; | 180 | ZigType *wanted_type; |
| 180 | ZigType *actual_type; | 181 | ZigType *actual_type; |
| 181 | }; | 182 | }; |
| 182 | | 183 | |
| 183 | struct ConstCastBadCV { | 184 | struct ConstCastPtrSentinel { |
| 184 | ZigType *wanted_type; | 185 | ZigType *wanted_type; |
| 185 | ZigType *actual_type; | | |
| 186 | }; | 186 | }; |
| 187 | | 187 | |
| 188 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); | 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,8 +264,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c |
| 264 | case ConstPtrSpecialBaseArray: { | 264 | case ConstPtrSpecialBaseArray: { |
| 265 | ConstExprValue *array_val = const_val->data.x_ptr.data.base_array.array_val; | 265 | ConstExprValue *array_val = const_val->data.x_ptr.data.base_array.array_val; |
| 266 | if (const_val->data.x_ptr.data.base_array.elem_index == array_val->type->data.array.len) { | 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); | 267 | result = array_val->type->data.array.sentinel; |
| 268 | result = get_null_value(array_val->type->data.array.child_type); | | |
| 269 | } else { | 268 | } else { |
| 270 | expand_undef_array(g, array_val); | 269 | expand_undef_array(g, array_val); |
| 271 | result = &array_val->data.x_array.data.s_none.elements[const_val->data.x_ptr.data.base_array.elem_index]; | 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,7 +316,7 @@ static bool slice_is_const(ZigType *type) { |
| 317 | | 316 | |
| 318 | // This function returns true when you can change the type of a ConstExprValue and the | 317 | // This function returns true when you can change the type of a ConstExprValue and the |
| 319 | // value remains meaningful. | 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 | if (expected == actual) | 320 | if (expected == actual) |
| 322 | return true; | 321 | return true; |
| 323 | | 322 | |
| ... | @@ -366,7 +365,8 @@ static bool types_have_same_zig_comptime_repr(ZigType *expected, ZigType *actual | ... | @@ -366,7 +365,8 @@ static bool types_have_same_zig_comptime_repr(ZigType *expected, ZigType *actual |
| 366 | case ZigTypeIdArray: | 365 | case ZigTypeIdArray: |
| 367 | return expected->data.array.len == actual->data.array.len && | 366 | return expected->data.array.len == actual->data.array.len && |
| 368 | expected->data.array.child_type == actual->data.array.child_type && | 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 | zig_unreachable(); | 371 | zig_unreachable(); |
| 372 | } | 372 | } |
| ... | @@ -1576,9 +1576,11 @@ static IrInstruction *ir_build_br(IrBuilder *irb, Scope *scope, AstNode *source_ | ... | @@ -1576,9 +1576,11 @@ static IrInstruction *ir_build_br(IrBuilder *irb, Scope *scope, AstNode *source_ |
| 1576 | | 1576 | |
| 1577 | static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node, | 1577 | static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1578 | IrInstruction *child_type, bool is_const, bool is_volatile, PtrLen ptr_len, | 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 | IrInstructionPtrType *ptr_type_of_instruction = ir_build_instruction<IrInstructionPtrType>(irb, scope, source_node); | 1582 | IrInstructionPtrType *ptr_type_of_instruction = ir_build_instruction<IrInstructionPtrType>(irb, scope, source_node); |
| | 1583 | ptr_type_of_instruction->sentinel = sentinel; |
| 1582 | ptr_type_of_instruction->align_value = align_value; | 1584 | ptr_type_of_instruction->align_value = align_value; |
| 1583 | ptr_type_of_instruction->child_type = child_type; | 1585 | ptr_type_of_instruction->child_type = child_type; |
| 1584 | ptr_type_of_instruction->is_const = is_const; | 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,6 +1590,7 @@ static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *s |
| 1588 | ptr_type_of_instruction->host_int_bytes = host_int_bytes; | 1590 | ptr_type_of_instruction->host_int_bytes = host_int_bytes; |
| 1589 | ptr_type_of_instruction->is_allow_zero = is_allow_zero; | 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 | if (align_value) ir_ref_instruction(align_value, irb->current_basic_block); | 1594 | if (align_value) ir_ref_instruction(align_value, irb->current_basic_block); |
| 1592 | ir_ref_instruction(child_type, irb->current_basic_block); | 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,14 +1807,15 @@ static IrInstruction *ir_build_set_float_mode(IrBuilder *irb, Scope *scope, AstN |
| 1804 | } | 1807 | } |
| 1805 | | 1808 | |
| 1806 | static IrInstruction *ir_build_array_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *size, | 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 | IrInstructionArrayType *instruction = ir_build_instruction<IrInstructionArrayType>(irb, scope, source_node); | 1812 | IrInstructionArrayType *instruction = ir_build_instruction<IrInstructionArrayType>(irb, scope, source_node); |
| 1810 | instruction->size = size; | 1813 | instruction->size = size; |
| | 1814 | instruction->sentinel = sentinel; |
| 1811 | instruction->child_type = child_type; | 1815 | instruction->child_type = child_type; |
| 1812 | instruction->is_null_terminated = is_null_terminated; | | |
| 1813 | | 1816 | |
| 1814 | ir_ref_instruction(size, irb->current_basic_block); | 1817 | ir_ref_instruction(size, irb->current_basic_block); |
| | 1818 | if (sentinel != nullptr) ir_ref_instruction(sentinel, irb->current_basic_block); |
| 1815 | ir_ref_instruction(child_type, irb->current_basic_block); | 1819 | ir_ref_instruction(child_type, irb->current_basic_block); |
| 1816 | | 1820 | |
| 1817 | return &instruction->base; | 1821 | return &instruction->base; |
| ... | @@ -1827,20 +1831,22 @@ static IrInstruction *ir_build_anyframe_type(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -1827,20 +1831,22 @@ static IrInstruction *ir_build_anyframe_type(IrBuilder *irb, Scope *scope, AstNo |
| 1827 | | 1831 | |
| 1828 | return &instruction->base; | 1832 | return &instruction->base; |
| 1829 | } | 1833 | } |
| | 1834 | |
| 1830 | static IrInstruction *ir_build_slice_type(IrBuilder *irb, Scope *scope, AstNode *source_node, | 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, | 1836 | IrInstruction *child_type, bool is_const, bool is_volatile, |
| 1832 | bool is_null_terminated) | 1837 | IrInstruction *sentinel, IrInstruction *align_value, bool is_allow_zero) |
| 1833 | { | 1838 | { |
| 1834 | IrInstructionSliceType *instruction = ir_build_instruction<IrInstructionSliceType>(irb, scope, source_node); | 1839 | IrInstructionSliceType *instruction = ir_build_instruction<IrInstructionSliceType>(irb, scope, source_node); |
| 1835 | instruction->is_const = is_const; | 1840 | instruction->is_const = is_const; |
| 1836 | instruction->is_volatile = is_volatile; | 1841 | instruction->is_volatile = is_volatile; |
| 1837 | instruction->child_type = child_type; | 1842 | instruction->child_type = child_type; |
| | 1843 | instruction->sentinel = sentinel; |
| 1838 | instruction->align_value = align_value; | 1844 | instruction->align_value = align_value; |
| 1839 | instruction->is_allow_zero = is_allow_zero; | 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 | ir_ref_instruction(child_type, irb->current_basic_block); | 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 | return &instruction->base; | 1851 | return &instruction->base; |
| 1846 | } | 1852 | } |
| ... | @@ -6067,9 +6073,9 @@ static PtrLen star_token_to_ptr_len(TokenId token_id) { | ... | @@ -6067,9 +6073,9 @@ static PtrLen star_token_to_ptr_len(TokenId token_id) { |
| 6067 | case TokenIdStar: | 6073 | case TokenIdStar: |
| 6068 | case TokenIdStarStar: | 6074 | case TokenIdStarStar: |
| 6069 | return PtrLenSingle; | 6075 | return PtrLenSingle; |
| 6070 | case TokenIdBracketStarBracket: | 6076 | case TokenIdLBracket: |
| 6071 | return PtrLenUnknown; | 6077 | return PtrLenUnknown; |
| 6072 | case TokenIdBracketStarCBracket: | 6078 | case TokenIdSymbol: |
| 6073 | return PtrLenC; | 6079 | return PtrLenC; |
| 6074 | default: | 6080 | default: |
| 6075 | zig_unreachable(); | 6081 | zig_unreachable(); |
| ... | @@ -6080,22 +6086,22 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -6080,22 +6086,22 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode |
| 6080 | assert(node->type == NodeTypePointerType); | 6086 | assert(node->type == NodeTypePointerType); |
| 6081 | | 6087 | |
| 6082 | PtrLen ptr_len = star_token_to_ptr_len(node->data.pointer_type.star_token->id); | 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 | bool is_const = node->data.pointer_type.is_const; | 6090 | bool is_const = node->data.pointer_type.is_const; |
| 6094 | bool is_volatile = node->data.pointer_type.is_volatile; | 6091 | bool is_volatile = node->data.pointer_type.is_volatile; |
| 6095 | bool is_allow_zero = node->data.pointer_type.allow_zero_token != nullptr; | 6092 | bool is_allow_zero = node->data.pointer_type.allow_zero_token != nullptr; |
| | 6093 | AstNode *sentinel_expr = node->data.pointer_type.sentinel; |
| 6096 | AstNode *expr_node = node->data.pointer_type.op_expr; | 6094 | AstNode *expr_node = node->data.pointer_type.op_expr; |
| 6097 | AstNode *align_expr = node->data.pointer_type.align_expr; | 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 | IrInstruction *align_value; | 6106 | IrInstruction *align_value; |
| 6101 | if (align_expr != nullptr) { | 6107 | if (align_expr != nullptr) { |
| ... | @@ -6141,7 +6147,7 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode | ... | @@ -6141,7 +6147,7 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode |
| 6141 | } | 6147 | } |
| 6142 | | 6148 | |
| 6143 | return ir_build_ptr_type(irb, scope, node, child_type, is_const, is_volatile, | 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 | static IrInstruction *ir_gen_catch_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node, | 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,13 +6251,22 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A |
| 6245 | buf_sprintf("initializing array with struct syntax")); | 6251 | buf_sprintf("initializing array with struct syntax")); |
| 6246 | return irb->codegen->invalid_instruction; | 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 | IrInstruction *elem_type = ir_gen_node(irb, | 6263 | IrInstruction *elem_type = ir_gen_node(irb, |
| 6249 | container_init_expr->type->data.inferred_array_type.child_type, scope); | 6264 | container_init_expr->type->data.inferred_array_type.child_type, scope); |
| 6250 | if (elem_type == irb->codegen->invalid_instruction) | 6265 | if (elem_type == irb->codegen->invalid_instruction) |
| 6251 | return elem_type; | 6266 | return elem_type; |
| 6252 | size_t item_count = container_init_expr->entries.length; | 6267 | size_t item_count = container_init_expr->entries.length; |
| 6253 | IrInstruction *item_count_inst = ir_build_const_usize(irb, scope, node, item_count); | 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 | } else { | 6270 | } else { |
| 6256 | container_type = ir_gen_node(irb, container_init_expr->type, scope); | 6271 | container_type = ir_gen_node(irb, container_init_expr->type, scope); |
| 6257 | if (container_type == irb->codegen->invalid_instruction) | 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,10 +6990,20 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *n |
| 6975 | bool is_const = node->data.array_type.is_const; | 6990 | bool is_const = node->data.array_type.is_const; |
| 6976 | bool is_volatile = node->data.array_type.is_volatile; | 6991 | bool is_volatile = node->data.array_type.is_volatile; |
| 6977 | bool is_allow_zero = node->data.array_type.allow_zero_token != nullptr; | 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 | AstNode *align_expr = node->data.array_type.align_expr; | 6994 | AstNode *align_expr = node->data.array_type.align_expr; |
| 6980 | | 6995 | |
| 6981 | Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); | 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 | if (size_node) { | 7007 | if (size_node) { |
| 6983 | if (is_const) { | 7008 | if (is_const) { |
| 6984 | add_node_error(irb->codegen, node, buf_create_from_str("const qualifier invalid on array type")); | 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,7 +7030,7 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *n |
| 7005 | if (child_type == irb->codegen->invalid_instruction) | 7030 | if (child_type == irb->codegen->invalid_instruction) |
| 7006 | return child_type; | 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 | } else { | 7034 | } else { |
| 7010 | IrInstruction *align_value; | 7035 | IrInstruction *align_value; |
| 7011 | if (align_expr != nullptr) { | 7036 | if (align_expr != nullptr) { |
| ... | @@ -7020,8 +7045,8 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -7020,8 +7045,8 @@ static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *n |
| 7020 | if (child_type == irb->codegen->invalid_instruction) | 7045 | if (child_type == irb->codegen->invalid_instruction) |
| 7021 | return child_type; | 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, | 7048 | return ir_build_slice_type(irb, scope, node, child_type, is_const, is_volatile, sentinel, |
| 7024 | is_null_terminated); | 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,7 +8723,7 @@ ConstExprValue *const_ptr_pointee(IrAnalyze *ira, CodeGen *codegen, ConstExprVal |
| 8698 | case OnePossibleValueYes: | 8723 | case OnePossibleValueYes: |
| 8699 | return get_the_one_possible_value(codegen, expected_type); | 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 | if ((err = eval_comptime_ptr_reinterpret(ira, codegen, source_node, const_val))) | 8727 | if ((err = eval_comptime_ptr_reinterpret(ira, codegen, source_node, const_val))) |
| 8703 | return nullptr; | 8728 | return nullptr; |
| 8704 | return const_ptr_pointee_unchecked(codegen, const_val); | 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,7 +9871,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted |
| 9846 | // alignment can be decreased | 9871 | // alignment can be decreased |
| 9847 | // bit offset attributes must match exactly | 9872 | // bit offset attributes must match exactly |
| 9848 | // PtrLenSingle/PtrLenUnknown must match exactly, but PtrLenC matches either one | 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 | ZigType *wanted_ptr_type = get_src_ptr_type(wanted_type); | 9875 | ZigType *wanted_ptr_type = get_src_ptr_type(wanted_type); |
| 9851 | ZigType *actual_ptr_type = get_src_ptr_type(actual_type); | 9876 | ZigType *actual_ptr_type = get_src_ptr_type(actual_type); |
| 9852 | bool wanted_allows_zero = ptr_allows_addr_zero(wanted_type); | 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,15 +9883,20 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted |
| 9858 | bool actual_opt_or_ptr = actual_ptr_type != nullptr && | 9883 | bool actual_opt_or_ptr = actual_ptr_type != nullptr && |
| 9859 | (actual_type->id == ZigTypeIdPointer || actual_type->id == ZigTypeIdOptional); | 9884 | (actual_type->id == ZigTypeIdPointer || actual_type->id == ZigTypeIdOptional); |
| 9860 | if (wanted_opt_or_ptr && actual_opt_or_ptr) { | 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 | bool ok_null_term_ptrs = | 9886 | bool ok_null_term_ptrs = |
| 9863 | actual_ptr_type->data.pointer.ptr_len == PtrLenNull || | 9887 | wanted_ptr_type->data.pointer.sentinel == nullptr || |
| 9864 | wanted_ptr_type->data.pointer.ptr_len == PtrLenUnknown; | 9888 | (actual_ptr_type->data.pointer.sentinel != nullptr && |
| 9865 | if (!(ptr_lens_equal || wanted_is_c_ptr || actual_is_c_ptr || ok_null_term_ptrs)) { | 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 | result.id = ConstCastResultIdPtrLens; | 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 | return result; | 9900 | return result; |
| 9871 | } | 9901 | } |
| 9872 | | 9902 | |
| ... | @@ -9944,14 +9974,15 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted | ... | @@ -9944,14 +9974,15 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted |
| 9944 | result.data.array_mismatch->actual_child = actual_type->data.array.child_type; | 9974 | result.data.array_mismatch->actual_child = actual_type->data.array.child_type; |
| 9945 | return result; | 9975 | return result; |
| 9946 | } | 9976 | } |
| 9947 | bool ok_null_terminated = !wanted_type->data.array.is_null_terminated || | 9977 | bool ok_null_terminated = (wanted_type->data.array.sentinel == nullptr) || |
| 9948 | actual_type->data.array.is_null_terminated; | 9978 | (actual_type->data.array.sentinel != nullptr && |
| | 9979 | const_values_equal(ira->codegen, wanted_type->data.array.sentinel, actual_type->data.array.sentinel)); |
| 9949 | if (!ok_null_terminated) { | 9980 | if (!ok_null_terminated) { |
| 9950 | result.id = ConstCastResultIdBadNullTermArrays; | 9981 | result.id = ConstCastResultIdSentinelArrays; |
| 9951 | result.data.bad_null_term_arrays = allocate_nonzero<ConstCastBadNullTermArrays>(1); | 9982 | result.data.sentinel_arrays = allocate_nonzero<ConstCastBadNullTermArrays>(1); |
| 9952 | result.data.bad_null_term_arrays->child = child; | 9983 | result.data.sentinel_arrays->child = child; |
| 9953 | result.data.bad_null_term_arrays->wanted_type = wanted_type; | 9984 | result.data.sentinel_arrays->wanted_type = wanted_type; |
| 9954 | result.data.bad_null_term_arrays->actual_type = actual_type; | 9985 | result.data.sentinel_arrays->actual_type = actual_type; |
| 9955 | return result; | 9986 | return result; |
| 9956 | } | 9987 | } |
| 9957 | return result; | 9988 | return result; |
| ... | @@ -10781,8 +10812,12 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT | ... | @@ -10781,8 +10812,12 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 10781 | prev_type->data.pointer.child_type->id == ZigTypeIdArray && | 10812 | prev_type->data.pointer.child_type->id == ZigTypeIdArray && |
| 10782 | (cur_type->data.pointer.is_const || !prev_type->data.pointer.is_const || | 10813 | (cur_type->data.pointer.is_const || !prev_type->data.pointer.is_const || |
| 10783 | prev_type->data.pointer.child_type->data.array.len == 0) && | 10814 | prev_type->data.pointer.child_type->data.array.len == 0) && |
| 10784 | (cur_type->data.pointer.child_type->data.array.is_null_terminated || | 10815 | ( |
| 10785 | !prev_type->data.pointer.child_type->data.array.is_null_terminated) && | 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 | types_match_const_cast_only(ira, | 10821 | types_match_const_cast_only(ira, |
| 10787 | cur_type->data.pointer.child_type->data.array.child_type, | 10822 | cur_type->data.pointer.child_type->data.array.child_type, |
| 10788 | prev_type->data.pointer.child_type->data.array.child_type, | 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,8 +10833,12 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 10798 | cur_type->data.pointer.child_type->id == ZigTypeIdArray && | 10833 | cur_type->data.pointer.child_type->id == ZigTypeIdArray && |
| 10799 | (prev_type->data.pointer.is_const || !cur_type->data.pointer.is_const || | 10834 | (prev_type->data.pointer.is_const || !cur_type->data.pointer.is_const || |
| 10800 | cur_type->data.pointer.child_type->data.array.len == 0) && | 10835 | cur_type->data.pointer.child_type->data.array.len == 0) && |
| 10801 | (prev_type->data.pointer.child_type->data.array.is_null_terminated || | 10836 | ( |
| 10802 | !cur_type->data.pointer.child_type->data.array.is_null_terminated) && | 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 | types_match_const_cast_only(ira, | 10842 | types_match_const_cast_only(ira, |
| 10804 | prev_type->data.pointer.child_type->data.array.child_type, | 10843 | prev_type->data.pointer.child_type->data.array.child_type, |
| 10805 | cur_type->data.pointer.child_type->data.array.child_type, | 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,11 +10910,12 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 10871 | } else if (prev_inst->value.type->id == ZigTypeIdPointer) { | 10910 | } else if (prev_inst->value.type->id == ZigTypeIdPointer) { |
| 10872 | ZigType *array_type = prev_inst->value.type->data.pointer.child_type; | 10911 | ZigType *array_type = prev_inst->value.type->data.pointer.child_type; |
| 10873 | src_assert(array_type->id == ZigTypeIdArray, source_node); | 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 | ira->codegen, array_type->data.array.child_type, | 10914 | ira->codegen, array_type->data.array.child_type, |
| 10876 | prev_inst->value.type->data.pointer.is_const, false, | 10915 | prev_inst->value.type->data.pointer.is_const, false, |
| 10877 | array_type->data.array.is_null_terminated ? PtrLenNull : PtrLenUnknown, | 10916 | PtrLenUnknown, |
| 10878 | 0, 0, 0, false); | 10917 | 0, 0, 0, false, |
| | 10918 | VECTOR_INDEX_NONE, nullptr, array_type->data.array.sentinel); |
| 10879 | ZigType *slice_type = get_slice_type(ira->codegen, ptr_type); | 10919 | ZigType *slice_type = get_slice_type(ira->codegen, ptr_type); |
| 10880 | if (err_set_type != nullptr) { | 10920 | if (err_set_type != nullptr) { |
| 10881 | return get_error_union_type(ira->codegen, err_set_type, slice_type); | 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,7 +11722,7 @@ static IrInstruction *ir_analyze_optional_wrap(IrAnalyze *ira, IrInstruction *so |
| 11682 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, | 11722 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, |
| 11683 | source_instr->scope, source_instr->source_node); | 11723 | source_instr->scope, source_instr->source_node); |
| 11684 | const_instruction->base.value.special = ConstValSpecialStatic; | 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 | copy_const_val(&const_instruction->base.value, val, val->data.x_ptr.mut == ConstPtrMutComptimeConst); | 11726 | copy_const_val(&const_instruction->base.value, val, val->data.x_ptr.mut == ConstPtrMutComptimeConst); |
| 11687 | } else { | 11727 | } else { |
| 11688 | const_instruction->base.value.data.x_optional = val; | 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,14 +12641,24 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa |
| 12601 | break; | 12641 | break; |
| 12602 | } | 12642 | } |
| 12603 | case ConstCastResultIdPtrLens: { | 12643 | case ConstCastResultIdPtrLens: { |
| 12604 | ZigType *wanted_type = cast_result->data.bad_ptr_lens->wanted_type; | 12644 | add_error_note(ira->codegen, parent_msg, source_node, |
| 12605 | ZigType *actual_type = cast_result->data.bad_ptr_lens->actual_type; | 12645 | buf_sprintf("pointer length mismatch")); |
| 12606 | bool wanted_null_term = wanted_type->data.pointer.ptr_len == PtrLenNull; | 12646 | break; |
| 12607 | bool actual_null_term = actual_type->data.pointer.ptr_len == PtrLenNull; | 12647 | } |
| 12608 | if (wanted_null_term && !actual_null_term) { | 12648 | case ConstCastResultIdPtrSentinel: { |
| 12609 | add_error_note(ira->codegen, parent_msg, source_node, | 12649 | ZigType *wanted_type = cast_result->data.bad_ptr_sentinel->wanted_type; |
| 12610 | buf_sprintf("destination type requires null termination")); | 12650 | Buf *msg = buf_sprintf("destination pointer requires a terminating '"); |
| 12611 | } | 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 | break; | 12662 | break; |
| 12613 | } | 12663 | } |
| 12614 | case ConstCastResultIdCV: { | 12664 | case ConstCastResultIdCV: { |
| ... | @@ -12642,7 +12692,6 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa | ... | @@ -12642,7 +12692,6 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa |
| 12642 | case ConstCastResultIdUnresolvedInferredErrSet: // TODO | 12692 | case ConstCastResultIdUnresolvedInferredErrSet: // TODO |
| 12643 | case ConstCastResultIdAsyncAllocatorType: // TODO | 12693 | case ConstCastResultIdAsyncAllocatorType: // TODO |
| 12644 | case ConstCastResultIdArrayChild: // TODO | 12694 | case ConstCastResultIdArrayChild: // TODO |
| 12645 | case ConstCastResultIdBadNullTermArrays: // TODO | | |
| 12646 | break; | 12695 | break; |
| 12647 | } | 12696 | } |
| 12648 | } | 12697 | } |
| ... | @@ -13013,16 +13062,18 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -13013,16 +13062,18 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 13013 | | 13062 | |
| 13014 | // *[N]T to [*]T and [*c]T | 13063 | // *[N]T to [*]T and [*c]T |
| 13015 | if (wanted_type->id == ZigTypeIdPointer && | 13064 | if (wanted_type->id == ZigTypeIdPointer && |
| 13016 | (wanted_type->data.pointer.ptr_len == PtrLenUnknown || wanted_type->data.pointer.ptr_len == PtrLenC || | 13065 | (wanted_type->data.pointer.ptr_len == PtrLenUnknown || wanted_type->data.pointer.ptr_len == PtrLenC) && |
| 13017 | wanted_type->data.pointer.ptr_len == PtrLenNull) && | | |
| 13018 | actual_type->id == ZigTypeIdPointer && | 13066 | actual_type->id == ZigTypeIdPointer && |
| 13019 | actual_type->data.pointer.ptr_len == PtrLenSingle && | 13067 | actual_type->data.pointer.ptr_len == PtrLenSingle && |
| 13020 | actual_type->data.pointer.child_type->id == ZigTypeIdArray && | 13068 | actual_type->data.pointer.child_type->id == ZigTypeIdArray && |
| 13021 | (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) && | 13069 | (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) && |
| 13022 | (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile)) | 13070 | (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile)) |
| 13023 | { | 13071 | { |
| 13024 | if (wanted_type->data.pointer.ptr_len != PtrLenNull || | 13072 | ZigType *actual_array_type = actual_type->data.pointer.child_type; |
| 13025 | actual_type->data.pointer.child_type->data.array.is_null_terminated) | 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 | if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) | 13078 | if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) |
| 13028 | return ira->codegen->invalid_instruction; | 13079 | return ira->codegen->invalid_instruction; |
| ... | @@ -14741,7 +14792,6 @@ static bool is_pointer_arithmetic_allowed(ZigType *lhs_type, IrBinOp op) { | ... | @@ -14741,7 +14792,6 @@ static bool is_pointer_arithmetic_allowed(ZigType *lhs_type, IrBinOp op) { |
| 14741 | case PtrLenSingle: | 14792 | case PtrLenSingle: |
| 14742 | return lhs_type->data.pointer.child_type->id == ZigTypeIdArray; | 14793 | return lhs_type->data.pointer.child_type->id == ZigTypeIdArray; |
| 14743 | case PtrLenUnknown: | 14794 | case PtrLenUnknown: |
| 14744 | case PtrLenNull: | | |
| 14745 | case PtrLenC: | 14795 | case PtrLenC: |
| 14746 | return true; | 14796 | return true; |
| 14747 | } | 14797 | } |
| ... | @@ -15007,7 +15057,7 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i | ... | @@ -15007,7 +15057,7 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15007 | if (!op2_val) | 15057 | if (!op2_val) |
| 15008 | return ira->codegen->invalid_instruction; | 15058 | return ira->codegen->invalid_instruction; |
| 15009 | | 15059 | |
| 15010 | bool is_null_terminated = false; | 15060 | ConstExprValue *sentinel1 = nullptr; |
| 15011 | ConstExprValue *op1_array_val; | 15061 | ConstExprValue *op1_array_val; |
| 15012 | size_t op1_array_index; | 15062 | size_t op1_array_index; |
| 15013 | size_t op1_array_end; | 15063 | size_t op1_array_end; |
| ... | @@ -15017,16 +15067,17 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i | ... | @@ -15017,16 +15067,17 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15017 | op1_array_val = op1_val; | 15067 | op1_array_val = op1_val; |
| 15018 | op1_array_index = 0; | 15068 | op1_array_index = 0; |
| 15019 | op1_array_end = op1_type->data.array.len; | 15069 | op1_array_end = op1_type->data.array.len; |
| | 15070 | sentinel1 = op1_type->data.array.sentinel; |
| 15020 | } else if (op1_type->id == ZigTypeIdPointer && | 15071 | } else if (op1_type->id == ZigTypeIdPointer && |
| 15021 | op1_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && | 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 | op1_val->data.x_ptr.special == ConstPtrSpecialBaseArray) | 15074 | op1_val->data.x_ptr.special == ConstPtrSpecialBaseArray) |
| 15024 | { | 15075 | { |
| 15025 | child_type = op1_type->data.pointer.child_type; | 15076 | child_type = op1_type->data.pointer.child_type; |
| 15026 | op1_array_val = op1_val->data.x_ptr.data.base_array.array_val; | 15077 | op1_array_val = op1_val->data.x_ptr.data.base_array.array_val; |
| 15027 | op1_array_index = op1_val->data.x_ptr.data.base_array.elem_index; | 15078 | op1_array_index = op1_val->data.x_ptr.data.base_array.elem_index; |
| 15028 | op1_array_end = op1_array_val->type->data.array.len; | 15079 | op1_array_end = op1_array_val->type->data.array.len; |
| 15029 | is_null_terminated = true; | 15080 | sentinel1 = op1_type->data.pointer.sentinel; |
| 15030 | } else if (is_slice(op1_type)) { | 15081 | } else if (is_slice(op1_type)) { |
| 15031 | ZigType *ptr_type = op1_type->data.structure.fields[slice_ptr_index]->type_entry; | 15082 | ZigType *ptr_type = op1_type->data.structure.fields[slice_ptr_index]->type_entry; |
| 15032 | child_type = ptr_type->data.pointer.child_type; | 15083 | child_type = ptr_type->data.pointer.child_type; |
| ... | @@ -15036,6 +15087,7 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i | ... | @@ -15036,6 +15087,7 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15036 | op1_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; | 15087 | op1_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; |
| 15037 | ConstExprValue *len_val = op1_val->data.x_struct.fields[slice_len_index]; | 15088 | ConstExprValue *len_val = op1_val->data.x_struct.fields[slice_len_index]; |
| 15038 | op1_array_end = op1_array_index + bigint_as_usize(&len_val->data.x_bigint); | 15089 | op1_array_end = op1_array_index + bigint_as_usize(&len_val->data.x_bigint); |
| | 15090 | sentinel1 = ptr_type->data.pointer.sentinel; |
| 15039 | } else if (op1_type->id == ZigTypeIdPointer && op1_type->data.pointer.ptr_len == PtrLenSingle && | 15091 | } else if (op1_type->id == ZigTypeIdPointer && op1_type->data.pointer.ptr_len == PtrLenSingle && |
| 15040 | op1_type->data.pointer.child_type->id == ZigTypeIdArray) | 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,13 +15098,14 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15046 | return ira->codegen->invalid_instruction; | 15098 | return ira->codegen->invalid_instruction; |
| 15047 | op1_array_index = 0; | 15099 | op1_array_index = 0; |
| 15048 | op1_array_end = array_type->data.array.len; | 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 | } else { | 15102 | } else { |
| 15051 | ir_add_error(ira, op1, | 15103 | ir_add_error(ira, op1, |
| 15052 | buf_sprintf("expected array, found '%s'", buf_ptr(&op1->value.type->name))); | 15104 | buf_sprintf("expected array, found '%s'", buf_ptr(&op1->value.type->name))); |
| 15053 | return ira->codegen->invalid_instruction; | 15105 | return ira->codegen->invalid_instruction; |
| 15054 | } | 15106 | } |
| 15055 | | 15107 | |
| | 15108 | ConstExprValue *sentinel2 = nullptr; |
| 15056 | ConstExprValue *op2_array_val; | 15109 | ConstExprValue *op2_array_val; |
| 15057 | size_t op2_array_index; | 15110 | size_t op2_array_index; |
| 15058 | size_t op2_array_end; | 15111 | size_t op2_array_end; |
| ... | @@ -15062,15 +15115,17 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i | ... | @@ -15062,15 +15115,17 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15062 | op2_array_val = op2_val; | 15115 | op2_array_val = op2_val; |
| 15063 | op2_array_index = 0; | 15116 | op2_array_index = 0; |
| 15064 | op2_array_end = op2_array_val->type->data.array.len; | 15117 | op2_array_end = op2_array_val->type->data.array.len; |
| | 15118 | sentinel2 = op2_type->data.array.sentinel; |
| 15065 | } else if (op2_type->id == ZigTypeIdPointer && | 15119 | } else if (op2_type->id == ZigTypeIdPointer && |
| 15066 | op2_type->data.pointer.ptr_len == PtrLenNull && | 15120 | op2_type->data.pointer.sentinel != nullptr && |
| 15067 | op2_val->data.x_ptr.special == ConstPtrSpecialBaseArray) | 15121 | op2_val->data.x_ptr.special == ConstPtrSpecialBaseArray) |
| 15068 | { | 15122 | { |
| 15069 | op2_type_valid = op2_type->data.pointer.child_type == child_type; | 15123 | op2_type_valid = op2_type->data.pointer.child_type == child_type; |
| 15070 | op2_array_val = op2_val->data.x_ptr.data.base_array.array_val; | 15124 | op2_array_val = op2_val->data.x_ptr.data.base_array.array_val; |
| 15071 | op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index; | 15125 | op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index; |
| 15072 | op2_array_end = op2_array_val->type->data.array.len; | 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 | } else if (is_slice(op2_type)) { | 15129 | } else if (is_slice(op2_type)) { |
| 15075 | ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index]->type_entry; | 15130 | ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index]->type_entry; |
| 15076 | op2_type_valid = ptr_type->data.pointer.child_type == child_type; | 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,6 +15135,8 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15080 | op2_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; | 15135 | op2_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; |
| 15081 | ConstExprValue *len_val = op2_val->data.x_struct.fields[slice_len_index]; | 15136 | ConstExprValue *len_val = op2_val->data.x_struct.fields[slice_len_index]; |
| 15082 | op2_array_end = op2_array_index + bigint_as_usize(&len_val->data.x_bigint); | 15137 | op2_array_end = op2_array_index + bigint_as_usize(&len_val->data.x_bigint); |
| | 15138 | |
| | 15139 | sentinel2 = ptr_type->data.pointer.sentinel; |
| 15083 | } else if (op2_type->id == ZigTypeIdPointer && op2_type->data.pointer.ptr_len == PtrLenSingle && | 15140 | } else if (op2_type->id == ZigTypeIdPointer && op2_type->data.pointer.ptr_len == PtrLenSingle && |
| 15084 | op2_type->data.pointer.child_type->id == ZigTypeIdArray) | 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,7 +15147,8 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15090 | return ira->codegen->invalid_instruction; | 15147 | return ira->codegen->invalid_instruction; |
| 15091 | op2_array_index = 0; | 15148 | op2_array_index = 0; |
| 15092 | op2_array_end = array_type->data.array.len; | 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 | } else { | 15152 | } else { |
| 15095 | ir_add_error(ira, op2, | 15153 | ir_add_error(ira, op2, |
| 15096 | buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op2->value.type->name))); | 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,6 +15161,19 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15103 | return ira->codegen->invalid_instruction; | 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 | // The type of result is populated in the following if blocks | 15177 | // The type of result is populated in the following if blocks |
| 15107 | IrInstruction *result = ir_const(ira, &instruction->base, nullptr); | 15178 | IrInstruction *result = ir_const(ira, &instruction->base, nullptr); |
| 15108 | ConstExprValue *out_val = &result->value; | 15179 | ConstExprValue *out_val = &result->value; |
| ... | @@ -15110,24 +15181,25 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i | ... | @@ -15110,24 +15181,25 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15110 | ConstExprValue *out_array_val; | 15181 | ConstExprValue *out_array_val; |
| 15111 | size_t new_len = (op1_array_end - op1_array_index) + (op2_array_end - op2_array_index); | 15182 | size_t new_len = (op1_array_end - op1_array_index) + (op2_array_end - op2_array_index); |
| 15112 | if (op1_type->id == ZigTypeIdArray || op2_type->id == ZigTypeIdArray) { | 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 | out_array_val = out_val; | 15186 | out_array_val = out_val; |
| 15116 | } else if (op1_type->id == ZigTypeIdPointer || op2_type->id == ZigTypeIdPointer) { | 15187 | } else if (op1_type->id == ZigTypeIdPointer || op2_type->id == ZigTypeIdPointer) { |
| 15117 | out_array_val = create_const_vals(1); | 15188 | out_array_val = create_const_vals(1); |
| 15118 | out_array_val->special = ConstValSpecialStatic; | 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 | out_val->data.x_ptr.special = ConstPtrSpecialRef; | 15192 | out_val->data.x_ptr.special = ConstPtrSpecialRef; |
| 15122 | out_val->data.x_ptr.data.ref.pointee = out_array_val; | 15193 | out_val->data.x_ptr.data.ref.pointee = out_array_val; |
| 15123 | out_val->type = get_pointer_to_type(ira->codegen, out_array_val->type, true); | 15194 | out_val->type = get_pointer_to_type(ira->codegen, out_array_val->type, true); |
| 15124 | } else if (is_slice(op1_type) || is_slice(op2_type)) { | 15195 | } else if (is_slice(op1_type) || is_slice(op2_type)) { |
| 15125 | ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, child_type, | 15196 | ZigType *ptr_type = get_pointer_to_type_extra2(ira->codegen, child_type, |
| 15126 | true, false, PtrLenUnknown, 0, 0, 0, false); | 15197 | true, false, PtrLenUnknown, 0, 0, 0, false, |
| | 15198 | VECTOR_INDEX_NONE, nullptr, sentinel); |
| 15127 | result->value.type = get_slice_type(ira->codegen, ptr_type); | 15199 | result->value.type = get_slice_type(ira->codegen, ptr_type); |
| 15128 | out_array_val = create_const_vals(1); | 15200 | out_array_val = create_const_vals(1); |
| 15129 | out_array_val->special = ConstValSpecialStatic; | 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 | out_val->data.x_struct.fields = alloc_const_vals_ptrs(2); | 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,12 +15213,12 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15141 | out_val->data.x_struct.fields[slice_len_index]->special = ConstValSpecialStatic; | 15213 | out_val->data.x_struct.fields[slice_len_index]->special = ConstValSpecialStatic; |
| 15142 | bigint_init_unsigned(&out_val->data.x_struct.fields[slice_len_index]->data.x_bigint, new_len); | 15214 | bigint_init_unsigned(&out_val->data.x_struct.fields[slice_len_index]->data.x_bigint, new_len); |
| 15143 | } else { | 15215 | } else { |
| 15144 | result->value.type = get_pointer_to_type_extra(ira->codegen, child_type, true, false, PtrLenNull, | 15216 | result->value.type = get_pointer_to_type_extra2(ira->codegen, child_type, true, false, PtrLenUnknown, |
| 15145 | 0, 0, 0, false); | 15217 | 0, 0, 0, false, VECTOR_INDEX_NONE, nullptr, sentinel); |
| 15146 | | 15218 | |
| 15147 | out_array_val = create_const_vals(1); | 15219 | out_array_val = create_const_vals(1); |
| 15148 | out_array_val->special = ConstValSpecialStatic; | 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 | out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; | 15222 | out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; |
| 15151 | out_val->data.x_ptr.data.base_array.array_val = out_array_val; | 15223 | out_val->data.x_ptr.data.base_array.array_val = out_array_val; |
| 15152 | out_val->data.x_ptr.data.base_array.elem_index = 0; | 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,26 +15231,36 @@ static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *i |
| 15159 | return result; | 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 | // TODO handle the buf case here for an optimization | 15236 | // TODO handle the buf case here for an optimization |
| 15164 | expand_undef_array(ira->codegen, op1_array_val); | 15237 | expand_undef_array(ira->codegen, op1_array_val); |
| 15165 | expand_undef_array(ira->codegen, op2_array_val); | 15238 | expand_undef_array(ira->codegen, op2_array_val); |
| 15166 | | 15239 | |
| 15167 | size_t next_index = 0; | 15240 | size_t next_index = 0; |
| 15168 | for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { | 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], | 15242 | ConstExprValue *elem_dest_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); | 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 | for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) { | 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], | 15249 | ConstExprValue *elem_dest_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); | 15250 | copy_const_val(elem_dest_val, &op2_array_val->data.x_array.data.s_none.elements[i], false); |
| 15175 | } | 15251 | elem_dest_val->parent.id = ConstParentIdArray; |
| 15176 | if (next_index < new_len) { | 15252 | elem_dest_val->parent.data.p_array.array_val = out_array_val; |
| 15177 | ConstExprValue *null_byte = &out_array_val->data.x_array.data.s_none.elements[next_index]; | 15253 | elem_dest_val->parent.data.p_array.elem_index = next_index; |
| 15178 | init_const_unsigned_negative(null_byte, child_type, 0, false); | 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 | next_index += 1; | 15261 | next_index += 1; |
| 15180 | } | 15262 | } |
| 15181 | assert(next_index == new_len); | 15263 | assert(next_index == full_len); |
| 15182 | | 15264 | |
| 15183 | return result; | 15265 | return result; |
| 15184 | } | 15266 | } |
| ... | @@ -15230,7 +15312,7 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * | ... | @@ -15230,7 +15312,7 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * |
| 15230 | | 15312 | |
| 15231 | ZigType *child_type = array_type->data.array.child_type; | 15313 | ZigType *child_type = array_type->data.array.child_type; |
| 15232 | ZigType *result_array_type = get_array_type(ira->codegen, child_type, new_array_len, | 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 | IrInstruction *array_result; | 15317 | IrInstruction *array_result; |
| 15236 | if (array_val->special == ConstValSpecialUndef || array_val->data.x_array.special == ConstArraySpecialUndef) { | 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,7 +15332,7 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * |
| 15250 | | 15332 | |
| 15251 | // TODO optimize the buf case | 15333 | // TODO optimize the buf case |
| 15252 | expand_undef_array(ira->codegen, array_val); | 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 | out_val->data.x_array.data.s_none.elements = create_const_vals(new_array_len + extra_null_term); | 15336 | out_val->data.x_array.data.s_none.elements = create_const_vals(new_array_len + extra_null_term); |
| 15255 | | 15337 | |
| 15256 | uint64_t i = 0; | 15338 | uint64_t i = 0; |
| ... | @@ -15266,10 +15348,9 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * | ... | @@ -15266,10 +15348,9 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * |
| 15266 | } | 15348 | } |
| 15267 | assert(i == new_array_len); | 15349 | assert(i == new_array_len); |
| 15268 | | 15350 | |
| 15269 | if (array_type->data.array.is_null_terminated) { | 15351 | if (array_type->data.array.sentinel != nullptr) { |
| 15270 | ConstExprValue *null_value = get_null_value(array_type->data.array.child_type); | | |
| 15271 | ConstExprValue *elem_dest_val = &out_val->data.x_array.data.s_none.elements[i]; | 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 | elem_dest_val->parent.id = ConstParentIdArray; | 15354 | elem_dest_val->parent.id = ConstParentIdArray; |
| 15274 | elem_dest_val->parent.data.p_array.array_val = out_val; | 15355 | elem_dest_val->parent.data.p_array.array_val = out_val; |
| 15275 | elem_dest_val->parent.data.p_array.elem_index = i; | 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,7 +17646,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, CodeGen *codegen, AstNode *source |
| 17565 | size_t dst_size = type_size(codegen, out_val->type); | 17646 | size_t dst_size = type_size(codegen, out_val->type); |
| 17566 | | 17647 | |
| 17567 | if (dst_size <= src_size) { | 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 | copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut != ConstPtrMutComptimeVar); | 17650 | copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut != ConstPtrMutComptimeVar); |
| 17570 | return ErrorNone; | 17651 | return ErrorNone; |
| 17571 | } | 17652 | } |
| ... | @@ -18316,11 +18397,11 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct | ... | @@ -18316,11 +18397,11 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 18316 | uint64_t index = bigint_as_u64(&casted_elem_index->value.data.x_bigint); | 18397 | uint64_t index = bigint_as_u64(&casted_elem_index->value.data.x_bigint); |
| 18317 | if (array_type->id == ZigTypeIdArray) { | 18398 | if (array_type->id == ZigTypeIdArray) { |
| 18318 | uint64_t array_len = array_type->data.array.len; | 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 | ZigType *elem_type = array_type->data.array.child_type; | 18401 | ZigType *elem_type = array_type->data.array.child_type; |
| 18321 | IrInstruction *null_element = ir_const(ira, &elem_ptr_instruction->base, elem_type); | 18402 | IrInstruction *sentinel_elem = ir_const(ira, &elem_ptr_instruction->base, elem_type); |
| 18322 | null_element->value = *get_null_value(elem_type); | 18403 | copy_const_val(&sentinel_elem->value, array_type->data.array.sentinel, false); |
| 18323 | return ir_get_ref(ira, &elem_ptr_instruction->base, null_element, true, false); | 18404 | return ir_get_ref(ira, &elem_ptr_instruction->base, sentinel_elem, true, false); |
| 18324 | } | 18405 | } |
| 18325 | if (index >= array_len) { | 18406 | if (index >= array_len) { |
| 18326 | ir_add_error_node(ira, elem_ptr_instruction->base.source_node, | 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,7 +18418,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 18337 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, | 18418 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, |
| 18338 | elem_ptr_instruction->ptr_len, | 18419 | elem_ptr_instruction->ptr_len, |
| 18339 | get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, (uint32_t)index, | 18420 | get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, (uint32_t)index, |
| 18340 | nullptr); | 18421 | nullptr, nullptr); |
| 18341 | } else if (return_type->data.pointer.explicit_alignment != 0) { | 18422 | } else if (return_type->data.pointer.explicit_alignment != 0) { |
| 18342 | // figure out the largest alignment possible | 18423 | // figure out the largest alignment possible |
| 18343 | | 18424 | |
| ... | @@ -18457,7 +18538,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct | ... | @@ -18457,7 +18538,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 18457 | new_index = offset + index; | 18538 | new_index = offset + index; |
| 18458 | ZigType *array_type = array_ptr_val->data.x_ptr.data.base_array.array_val->type; | 18539 | ZigType *array_type = array_ptr_val->data.x_ptr.data.base_array.array_val->type; |
| 18459 | mem_size = array_type->data.array.len; | 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 | mem_size += 1; | 18542 | mem_size += 1; |
| 18462 | } | 18543 | } |
| 18463 | old_size = mem_size - offset; | 18544 | old_size = mem_size - offset; |
| ... | @@ -18579,7 +18660,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct | ... | @@ -18579,7 +18660,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 18579 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, | 18660 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, |
| 18580 | elem_ptr_instruction->ptr_len, | 18661 | elem_ptr_instruction->ptr_len, |
| 18581 | get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, VECTOR_INDEX_RUNTIME, | 18662 | get_ptr_align(ira->codegen, ptr_type), 0, host_vec_len, false, VECTOR_INDEX_RUNTIME, |
| 18582 | nullptr); | 18663 | nullptr, nullptr); |
| 18583 | } else { | 18664 | } else { |
| 18584 | // runtime known element index | 18665 | // runtime known element index |
| 18585 | switch (type_requires_comptime(ira->codegen, return_type)) { | 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,7 +18864,7 @@ static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_n |
| 18783 | ZigType *elem_type = ira->codegen->builtin_types.entry_var; | 18864 | ZigType *elem_type = ira->codegen->builtin_types.entry_var; |
| 18784 | ZigType *field_ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type, | 18865 | ZigType *field_ptr_type = get_pointer_to_type_extra2(ira->codegen, elem_type, |
| 18785 | container_ptr_type->data.pointer.is_const, container_ptr_type->data.pointer.is_volatile, | 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 | if (instr_is_comptime(container_ptr)) { | 18869 | if (instr_is_comptime(container_ptr)) { |
| 18789 | IrInstruction *result = ir_const(ira, source_instr, field_ptr_type); | 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,6 +19646,12 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| 19565 | return ira->codegen->invalid_instruction; | 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 | lazy_slice_type->elem_type = slice_type_instruction->child_type->child; | 19655 | lazy_slice_type->elem_type = slice_type_instruction->child_type->child; |
| 19569 | if (ir_resolve_type_lazy(ira, lazy_slice_type->elem_type) == nullptr) | 19656 | if (ir_resolve_type_lazy(ira, lazy_slice_type->elem_type) == nullptr) |
| 19570 | return ira->codegen->invalid_instruction; | 19657 | return ira->codegen->invalid_instruction; |
| ... | @@ -19572,7 +19659,6 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, | ... | @@ -19572,7 +19659,6 @@ static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, |
| 19572 | lazy_slice_type->is_const = slice_type_instruction->is_const; | 19659 | lazy_slice_type->is_const = slice_type_instruction->is_const; |
| 19573 | lazy_slice_type->is_volatile = slice_type_instruction->is_volatile; | 19660 | lazy_slice_type->is_volatile = slice_type_instruction->is_volatile; |
| 19574 | lazy_slice_type->is_allowzero = slice_type_instruction->is_allow_zero; | 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 | return result; | 19663 | return result; |
| 19578 | } | 19664 | } |
| ... | @@ -19647,6 +19733,22 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, | ... | @@ -19647,6 +19733,22 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, |
| 19647 | ZigType *child_type = ir_resolve_type(ira, child_type_value); | 19733 | ZigType *child_type = ir_resolve_type(ira, child_type_value); |
| 19648 | if (type_is_invalid(child_type)) | 19734 | if (type_is_invalid(child_type)) |
| 19649 | return ira->codegen->invalid_instruction; | 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 | switch (child_type->id) { | 19752 | switch (child_type->id) { |
| 19651 | case ZigTypeIdInvalid: // handled above | 19753 | case ZigTypeIdInvalid: // handled above |
| 19652 | zig_unreachable(); | 19754 | zig_unreachable(); |
| ... | @@ -19682,8 +19784,7 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, | ... | @@ -19682,8 +19784,7 @@ static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, |
| 19682 | { | 19784 | { |
| 19683 | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) | 19785 | if ((err = type_resolve(ira->codegen, child_type, ResolveStatusSizeKnown))) |
| 19684 | return ira->codegen->invalid_instruction; | 19786 | return ira->codegen->invalid_instruction; |
| 19685 | ZigType *result_type = get_array_type(ira->codegen, child_type, size, | 19787 | ZigType *result_type = get_array_type(ira->codegen, child_type, size, sentinel_val); |
| 19686 | array_type_instruction->is_null_terminated); | | |
| 19687 | return ir_const_type(ira, &array_type_instruction->base, result_type); | 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,7 +19903,7 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr |
| 19802 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, | 19903 | ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, |
| 19803 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0, false); | 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 | if (instr_is_comptime(base_ptr)) { | 19908 | if (instr_is_comptime(base_ptr)) { |
| 19808 | ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad); | 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,7 +20860,7 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, |
| 20759 | if (container_type->id == ZigTypeIdArray) { | 20860 | if (container_type->id == ZigTypeIdArray) { |
| 20760 | ZigType *child_type = container_type->data.array.child_type; | 20861 | ZigType *child_type = container_type->data.array.child_type; |
| 20761 | if (container_type->data.array.len != elem_count) { | 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 | ir_add_error(ira, &instruction->base, | 20865 | ir_add_error(ira, &instruction->base, |
| 20765 | buf_sprintf("expected %s literal, found %s literal", | 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,7 +21347,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr |
| 21246 | | 21347 | |
| 21247 | ConstExprValue *declaration_array = create_const_vals(1); | 21348 | ConstExprValue *declaration_array = create_const_vals(1); |
| 21248 | declaration_array->special = ConstValSpecialStatic; | 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 | declaration_array->data.x_array.special = ConstArraySpecialNone; | 21351 | declaration_array->data.x_array.special = ConstArraySpecialNone; |
| 21251 | declaration_array->data.x_array.data.s_none.elements = create_const_vals(declaration_count); | 21352 | declaration_array->data.x_array.data.s_none.elements = create_const_vals(declaration_count); |
| 21252 | init_const_slice(ira->codegen, out_val, declaration_array, 0, declaration_count, false); | 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,7 +21492,7 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInstruction *source_instr |
| 21391 | ConstExprValue *fn_arg_name_array = create_const_vals(1); | 21492 | ConstExprValue *fn_arg_name_array = create_const_vals(1); |
| 21392 | fn_arg_name_array->special = ConstValSpecialStatic; | 21493 | fn_arg_name_array->special = ConstValSpecialStatic; |
| 21393 | fn_arg_name_array->type = get_array_type(ira->codegen, | 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 | fn_arg_name_array->data.x_array.special = ConstArraySpecialNone; | 21496 | fn_arg_name_array->data.x_array.special = ConstArraySpecialNone; |
| 21396 | fn_arg_name_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); | 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,7 +21547,6 @@ static BuiltinPtrSize ptr_len_to_size_enum_index(PtrLen ptr_len) { |
| 21446 | case PtrLenSingle: | 21547 | case PtrLenSingle: |
| 21447 | return BuiltinPtrSizeOne; | 21548 | return BuiltinPtrSizeOne; |
| 21448 | case PtrLenUnknown: | 21549 | case PtrLenUnknown: |
| 21449 | case PtrLenNull: | | |
| 21450 | return BuiltinPtrSizeMany; | 21550 | return BuiltinPtrSizeMany; |
| 21451 | case PtrLenC: | 21551 | case PtrLenC: |
| 21452 | return BuiltinPtrSizeC; | 21552 | return BuiltinPtrSizeC; |
| ... | @@ -21527,11 +21627,21 @@ static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_ty | ... | @@ -21527,11 +21627,21 @@ static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_ty |
| 21527 | fields[5]->special = ConstValSpecialStatic; | 21627 | fields[5]->special = ConstValSpecialStatic; |
| 21528 | fields[5]->type = ira->codegen->builtin_types.entry_bool; | 21628 | fields[5]->type = ira->codegen->builtin_types.entry_bool; |
| 21529 | fields[5]->data.x_bool = attrs_type->data.pointer.allow_zero; | 21629 | fields[5]->data.x_bool = attrs_type->data.pointer.allow_zero; |
| 21530 | // is_null_terminated: bool | 21630 | // sentinel: ?*const c_void |
| 21531 | ensure_field_index(result->type, "is_null_terminated", 6); | 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 | fields[6]->special = ConstValSpecialStatic; | 21633 | fields[6]->special = ConstValSpecialStatic; |
| 21533 | fields[6]->type = ira->codegen->builtin_types.entry_bool; | 21634 | fields[6]->type = get_optional_type(ira->codegen, ptr_type); |
| 21534 | fields[6]->data.x_bool = attrs_type->data.pointer.ptr_len == PtrLenNull; | 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 | return result; | 21646 | return result; |
| 21537 | }; | 21647 | }; |
| ... | @@ -21652,11 +21762,22 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr | ... | @@ -21652,11 +21762,22 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 21652 | fields[1]->special = ConstValSpecialStatic; | 21762 | fields[1]->special = ConstValSpecialStatic; |
| 21653 | fields[1]->type = ira->codegen->builtin_types.entry_type; | 21763 | fields[1]->type = ira->codegen->builtin_types.entry_type; |
| 21654 | fields[1]->data.x_type = type_entry->data.array.child_type; | 21764 | fields[1]->data.x_type = type_entry->data.array.child_type; |
| 21655 | // is_null_terminated: bool | 21765 | // sentinel: ?*const c_void |
| 21656 | ensure_field_index(result->type, "is_null_terminated", 2); | | |
| 21657 | fields[2]->special = ConstValSpecialStatic; | 21766 | fields[2]->special = ConstValSpecialStatic; |
| 21658 | fields[2]->type = ira->codegen->builtin_types.entry_bool; | 21767 | ZigType *ptr_type = get_pointer_to_type(ira->codegen, |
| 21659 | fields[2]->data.x_bool = type_entry->data.array.is_null_terminated; | 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 | break; | 21782 | break; |
| 21662 | } | 21783 | } |
| ... | @@ -21744,7 +21865,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr | ... | @@ -21744,7 +21865,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 21744 | | 21865 | |
| 21745 | ConstExprValue *enum_field_array = create_const_vals(1); | 21866 | ConstExprValue *enum_field_array = create_const_vals(1); |
| 21746 | enum_field_array->special = ConstValSpecialStatic; | 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 | enum_field_array->data.x_array.special = ConstArraySpecialNone; | 21869 | enum_field_array->data.x_array.special = ConstArraySpecialNone; |
| 21749 | enum_field_array->data.x_array.data.s_none.elements = create_const_vals(enum_field_count); | 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,7 +21913,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 21792 | uint32_t error_count = type_entry->data.error_set.err_count; | 21913 | uint32_t error_count = type_entry->data.error_set.err_count; |
| 21793 | ConstExprValue *error_array = create_const_vals(1); | 21914 | ConstExprValue *error_array = create_const_vals(1); |
| 21794 | error_array->special = ConstValSpecialStatic; | 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 | error_array->data.x_array.special = ConstArraySpecialNone; | 21917 | error_array->data.x_array.special = ConstArraySpecialNone; |
| 21797 | error_array->data.x_array.data.s_none.elements = create_const_vals(error_count); | 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,7 +22009,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 21888 | | 22009 | |
| 21889 | ConstExprValue *union_field_array = create_const_vals(1); | 22010 | ConstExprValue *union_field_array = create_const_vals(1); |
| 21890 | union_field_array->special = ConstValSpecialStatic; | 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 | union_field_array->data.x_array.special = ConstArraySpecialNone; | 22013 | union_field_array->data.x_array.special = ConstArraySpecialNone; |
| 21893 | union_field_array->data.x_array.data.s_none.elements = create_const_vals(union_field_count); | 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,7 +22089,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 21968 | | 22089 | |
| 21969 | ConstExprValue *struct_field_array = create_const_vals(1); | 22090 | ConstExprValue *struct_field_array = create_const_vals(1); |
| 21970 | struct_field_array->special = ConstValSpecialStatic; | 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 | struct_field_array->data.x_array.special = ConstArraySpecialNone; | 22093 | struct_field_array->data.x_array.special = ConstArraySpecialNone; |
| 21973 | struct_field_array->data.x_array.data.s_none.elements = create_const_vals(struct_field_count); | 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,7 +22192,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr |
| 22071 | | 22192 | |
| 22072 | ConstExprValue *fn_arg_array = create_const_vals(1); | 22193 | ConstExprValue *fn_arg_array = create_const_vals(1); |
| 22073 | fn_arg_array->special = ConstValSpecialStatic; | 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 | fn_arg_array->data.x_array.special = ConstArraySpecialNone; | 22196 | fn_arg_array->data.x_array.special = ConstArraySpecialNone; |
| 22076 | fn_arg_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); | 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,6 +22290,17 @@ static ConstExprValue *get_const_field(IrAnalyze *ira, ConstExprValue *struct_va |
| 22169 | return struct_value->data.x_struct.fields[field_index]; | 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 | static bool get_const_field_bool(IrAnalyze *ira, ConstExprValue *struct_value, const char *name, size_t field_index) | 22304 | static bool get_const_field_bool(IrAnalyze *ira, ConstExprValue *struct_value, const char *name, size_t field_index) |
| 22173 | { | 22305 | { |
| 22174 | ConstExprValue *value = get_const_field(ira, struct_value, name, field_index); | 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,7 +22364,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi |
| 22232 | assert(size_value->type == ir_type_info_get_type(ira, "Size", type_info_pointer_type)); | 22364 | assert(size_value->type == ir_type_info_get_type(ira, "Size", type_info_pointer_type)); |
| 22233 | BuiltinPtrSize size_enum_index = (BuiltinPtrSize)bigint_as_u32(&size_value->data.x_enum_tag); | 22365 | BuiltinPtrSize size_enum_index = (BuiltinPtrSize)bigint_as_u32(&size_value->data.x_enum_tag); |
| 22234 | PtrLen ptr_len = size_enum_index_to_ptr_len(size_enum_index); | 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 | get_const_field_meta_type(ira, payload, "child", 4), | 22368 | get_const_field_meta_type(ira, payload, "child", 4), |
| 22237 | get_const_field_bool(ira, payload, "is_const", 1), | 22369 | get_const_field_bool(ira, payload, "is_const", 1), |
| 22238 | get_const_field_bool(ira, payload, "is_volatile", 2), | 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,7 +22372,10 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi |
| 22240 | bigint_as_u32(get_const_field_lit_int(ira, payload, "alignment", 3)), | 22372 | bigint_as_u32(get_const_field_lit_int(ira, payload, "alignment", 3)), |
| 22241 | 0, // bit_offset_in_host | 22373 | 0, // bit_offset_in_host |
| 22242 | 0, // host_int_bytes | 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 | if (size_enum_index != 2) | 22380 | if (size_enum_index != 2) |
| 22246 | return ptr_type; | 22381 | return ptr_type; |
| ... | @@ -22252,7 +22387,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi | ... | @@ -22252,7 +22387,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi |
| 22252 | return get_array_type(ira->codegen, | 22387 | return get_array_type(ira->codegen, |
| 22253 | get_const_field_meta_type(ira, payload, "child", 1), | 22388 | get_const_field_meta_type(ira, payload, "child", 1), |
| 22254 | bigint_as_u64(get_const_field_lit_int(ira, payload, "len", 0)), | 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 | case ZigTypeIdComptimeFloat: | 22392 | case ZigTypeIdComptimeFloat: |
| 22258 | return ira->codegen->builtin_types.entry_num_lit_float; | 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,7 +22770,7 @@ static IrInstruction *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstru |
| 22635 | } | 22770 | } |
| 22636 | | 22771 | |
| 22637 | ZigType *result_type = get_array_type(ira->codegen, | 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 | IrInstruction *result = ir_const(ira, &instruction->base, result_type); | 22774 | IrInstruction *result = ir_const(ira, &instruction->base, result_type); |
| 22640 | init_const_str_lit(ira->codegen, &result->value, file_contents); | 22775 | init_const_str_lit(ira->codegen, &result->value, file_contents); |
| 22641 | return result; | 22776 | return result; |
| ... | @@ -25858,6 +25993,12 @@ static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruct | ... | @@ -25858,6 +25993,12 @@ static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruct |
| 25858 | result->value.data.x_lazy = &lazy_ptr_type->base; | 25993 | result->value.data.x_lazy = &lazy_ptr_type->base; |
| 25859 | lazy_ptr_type->base.id = LazyValueIdPtrType; | 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 | lazy_ptr_type->elem_type = instruction->child_type->child; | 26002 | lazy_ptr_type->elem_type = instruction->child_type->child; |
| 25862 | if (ir_resolve_type_lazy(ira, lazy_ptr_type->elem_type) == nullptr) | 26003 | if (ir_resolve_type_lazy(ira, lazy_ptr_type->elem_type) == nullptr) |
| 25863 | return ira->codegen->invalid_instruction; | 26004 | return ira->codegen->invalid_instruction; |
| ... | @@ -27804,6 +27945,20 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ConstExprValue *val) { | ... | @@ -27804,6 +27945,20 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ConstExprValue *val) { |
| 27804 | if (type_is_invalid(elem_type)) | 27945 | if (type_is_invalid(elem_type)) |
| 27805 | return ErrorSemanticAnalyzeFail; | 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 | uint32_t align_bytes = 0; | 27962 | uint32_t align_bytes = 0; |
| 27808 | if (lazy_slice_type->align_inst != nullptr) { | 27963 | if (lazy_slice_type->align_inst != nullptr) { |
| 27809 | if (!ir_resolve_align(ira, lazy_slice_type->align_inst, elem_type, &align_bytes)) | 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,11 +28004,12 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ConstExprValue *val) { |
| 27849 | ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown; | 28004 | ResolveStatusZeroBitsKnown : ResolveStatusAlignmentKnown; |
| 27850 | if ((err = type_resolve(ira->codegen, elem_type, needed_status))) | 28005 | if ((err = type_resolve(ira->codegen, elem_type, needed_status))) |
| 27851 | return err; | 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 | lazy_slice_type->is_const, lazy_slice_type->is_volatile, | 28008 | lazy_slice_type->is_const, lazy_slice_type->is_volatile, |
| 27854 | lazy_slice_type->is_null_terminated ? PtrLenNull : PtrLenUnknown, | 28009 | PtrLenUnknown, |
| 27855 | align_bytes, | 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 | val->special = ConstValSpecialStatic; | 28013 | val->special = ConstValSpecialStatic; |
| 27858 | assert(val->type->id == ZigTypeIdMetaType); | 28014 | assert(val->type->id == ZigTypeIdMetaType); |
| 27859 | val->data.x_type = get_slice_type(ira->codegen, slice_ptr_type); | 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,6 +28023,20 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ConstExprValue *val) { |
| 27867 | if (type_is_invalid(elem_type)) | 28023 | if (type_is_invalid(elem_type)) |
| 27868 | return ErrorSemanticAnalyzeFail; | 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 | uint32_t align_bytes = 0; | 28040 | uint32_t align_bytes = 0; |
| 27871 | if (lazy_ptr_type->align_inst != nullptr) { | 28041 | if (lazy_ptr_type->align_inst != nullptr) { |
| 27872 | if (!ir_resolve_align(ira, lazy_ptr_type->align_inst, elem_type, &align_bytes)) | 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,10 +28079,10 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ConstExprValue *val) { |
| 27909 | } | 28079 | } |
| 27910 | bool allow_zero = lazy_ptr_type->is_allowzero || lazy_ptr_type->ptr_len == PtrLenC; | 28080 | bool allow_zero = lazy_ptr_type->is_allowzero || lazy_ptr_type->ptr_len == PtrLenC; |
| 27911 | assert(val->type->id == ZigTypeIdMetaType); | 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 | lazy_ptr_type->is_const, lazy_ptr_type->is_volatile, lazy_ptr_type->ptr_len, align_bytes, | 28083 | lazy_ptr_type->is_const, lazy_ptr_type->is_volatile, lazy_ptr_type->ptr_len, align_bytes, |
| 27914 | lazy_ptr_type->bit_offset_in_host, lazy_ptr_type->host_int_bytes, | 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 | val->special = ConstValSpecialStatic; | 28086 | val->special = ConstValSpecialStatic; |
| 27917 | return ErrorNone; | 28087 | return ErrorNone; |
| 27918 | } | 28088 | } |