| ... | @@ -12515,6 +12515,8 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio | ... | @@ -12515,6 +12515,8 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio |
| 12515 | zig_panic("TODO slice const inner struct"); | 12515 | zig_panic("TODO slice const inner struct"); |
| 12516 | case ConstPtrSpecialHardCodedAddr: | 12516 | case ConstPtrSpecialHardCodedAddr: |
| 12517 | array_val = nullptr; | 12517 | array_val = nullptr; |
| | 12518 | abs_offset = 0; |
| | 12519 | rel_end = SIZE_MAX; |
| 12518 | break; | 12520 | break; |
| 12519 | } | 12521 | } |
| 12520 | } else if (is_slice(array_type)) { | 12522 | } else if (is_slice(array_type)) { |
| ... | @@ -12540,69 +12542,72 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio | ... | @@ -12540,69 +12542,72 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio |
| 12540 | zig_panic("TODO slice const inner struct"); | 12542 | zig_panic("TODO slice const inner struct"); |
| 12541 | case ConstPtrSpecialHardCodedAddr: | 12543 | case ConstPtrSpecialHardCodedAddr: |
| 12542 | array_val = nullptr; | 12544 | array_val = nullptr; |
| | 12545 | abs_offset = 0; |
| | 12546 | rel_end = len_val->data.x_bignum.data.x_uint; |
| 12543 | break; | 12547 | break; |
| 12544 | } | 12548 | } |
| 12545 | } else { | 12549 | } else { |
| 12546 | zig_unreachable(); | 12550 | zig_unreachable(); |
| 12547 | } | 12551 | } |
| 12548 | | 12552 | |
| 12549 | if (array_val || parent_ptr->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { | 12553 | uint64_t start_scalar = casted_start->value.data.x_bignum.data.x_uint; |
| 12550 | uint64_t start_scalar = casted_start->value.data.x_bignum.data.x_uint; | 12554 | if (start_scalar > rel_end) { |
| 12551 | if (start_scalar > rel_end) { | 12555 | ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); |
| 12552 | ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); | 12556 | return ira->codegen->builtin_types.entry_invalid; |
| 12553 | return ira->codegen->builtin_types.entry_invalid; | 12557 | } |
| 12554 | } | | |
| 12555 | | 12558 | |
| 12556 | uint64_t end_scalar; | 12559 | uint64_t end_scalar; |
| 12557 | if (end) { | 12560 | if (end) { |
| 12558 | end_scalar = end->value.data.x_bignum.data.x_uint; | 12561 | end_scalar = end->value.data.x_bignum.data.x_uint; |
| 12559 | } else { | 12562 | } else { |
| 12560 | end_scalar = rel_end; | 12563 | end_scalar = rel_end; |
| 12561 | } | 12564 | } |
| 12562 | if (end_scalar > rel_end) { | 12565 | if (end_scalar > rel_end) { |
| 12563 | ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); | 12566 | ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); |
| 12564 | return ira->codegen->builtin_types.entry_invalid; | 12567 | return ira->codegen->builtin_types.entry_invalid; |
| 12565 | } | 12568 | } |
| 12566 | if (start_scalar > end_scalar) { | 12569 | if (start_scalar > end_scalar) { |
| 12567 | ir_add_error(ira, &instruction->base, buf_sprintf("slice start is greater than end")); | 12570 | ir_add_error(ira, &instruction->base, buf_sprintf("slice start is greater than end")); |
| 12568 | return ira->codegen->builtin_types.entry_invalid; | 12571 | return ira->codegen->builtin_types.entry_invalid; |
| 12569 | } | 12572 | } |
| 12570 | | 12573 | |
| 12571 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); | 12574 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); |
| 12572 | out_val->data.x_struct.fields = allocate<ConstExprValue>(2); | 12575 | out_val->data.x_struct.fields = allocate<ConstExprValue>(2); |
| 12573 | | 12576 | |
| 12574 | ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index]; | 12577 | ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index]; |
| 12575 | | 12578 | |
| 12576 | if (array_val) { | 12579 | if (array_val) { |
| 12577 | size_t index = abs_offset + start_scalar; | 12580 | size_t index = abs_offset + start_scalar; |
| 12578 | bool is_const = slice_is_const(return_type); | 12581 | bool is_const = slice_is_const(return_type); |
| 12579 | init_const_ptr_array(ira->codegen, ptr_val, array_val, index, is_const); | 12582 | init_const_ptr_array(ira->codegen, ptr_val, array_val, index, is_const); |
| 12580 | if (array_type->id == TypeTableEntryIdArray) { | 12583 | if (array_type->id == TypeTableEntryIdArray) { |
| 12581 | ptr_val->data.x_ptr.mut = ptr_ptr->value.data.x_ptr.mut; | 12584 | ptr_val->data.x_ptr.mut = ptr_ptr->value.data.x_ptr.mut; |
| 12582 | } | | |
| 12583 | } else { | | |
| 12584 | switch (parent_ptr->data.x_ptr.special) { | | |
| 12585 | case ConstPtrSpecialInvalid: | | |
| 12586 | case ConstPtrSpecialDiscard: | | |
| 12587 | zig_unreachable(); | | |
| 12588 | case ConstPtrSpecialRef: | | |
| 12589 | init_const_ptr_ref(ira->codegen, ptr_val, | | |
| 12590 | parent_ptr->data.x_ptr.data.ref.pointee, slice_is_const(return_type)); | | |
| 12591 | break; | | |
| 12592 | case ConstPtrSpecialBaseArray: | | |
| 12593 | zig_unreachable(); | | |
| 12594 | case ConstPtrSpecialBaseStruct: | | |
| 12595 | zig_panic("TODO"); | | |
| 12596 | case ConstPtrSpecialHardCodedAddr: | | |
| 12597 | zig_unreachable(); | | |
| 12598 | } | | |
| 12599 | } | 12585 | } |
| | 12586 | } else { |
| | 12587 | switch (parent_ptr->data.x_ptr.special) { |
| | 12588 | case ConstPtrSpecialInvalid: |
| | 12589 | case ConstPtrSpecialDiscard: |
| | 12590 | zig_unreachable(); |
| | 12591 | case ConstPtrSpecialRef: |
| | 12592 | init_const_ptr_ref(ira->codegen, ptr_val, |
| | 12593 | parent_ptr->data.x_ptr.data.ref.pointee, slice_is_const(return_type)); |
| | 12594 | break; |
| | 12595 | case ConstPtrSpecialBaseArray: |
| | 12596 | zig_unreachable(); |
| | 12597 | case ConstPtrSpecialBaseStruct: |
| | 12598 | zig_panic("TODO"); |
| | 12599 | case ConstPtrSpecialHardCodedAddr: |
| | 12600 | init_const_ptr_hard_coded_addr(ira->codegen, ptr_val, |
| | 12601 | parent_ptr->type->data.pointer.child_type, |
| | 12602 | parent_ptr->data.x_ptr.data.hard_coded_addr.addr + start_scalar, |
| | 12603 | slice_is_const(return_type)); |
| | 12604 | } |
| | 12605 | } |
| 12600 | | 12606 | |
| 12601 | ConstExprValue *len_val = &out_val->data.x_struct.fields[slice_len_index]; | 12607 | ConstExprValue *len_val = &out_val->data.x_struct.fields[slice_len_index]; |
| 12602 | init_const_usize(ira->codegen, len_val, end_scalar - start_scalar); | 12608 | init_const_usize(ira->codegen, len_val, end_scalar - start_scalar); |
| 12603 | | 12609 | |
| 12604 | return return_type; | 12610 | return return_type; |
| 12605 | } | | |
| 12606 | } | 12611 | } |
| 12607 | | 12612 | |
| 12608 | IrInstruction *new_instruction = ir_build_slice_from(&ira->new_irb, &instruction->base, ptr_ptr, | 12613 | IrInstruction *new_instruction = ir_build_slice_from(&ira->new_irb, &instruction->base, ptr_ptr, |