| ... | @@ -8183,7 +8183,7 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi | ... | @@ -8183,7 +8183,7 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi |
| 8183 | } | 8183 | } |
| 8184 | | 8184 | |
| 8185 | if (instr_is_comptime(value)) { | 8185 | if (instr_is_comptime(value)) { |
| 8186 | ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); | 8186 | ConstExprValue *val = ir_resolve_const(ira, value, UndefOk); |
| 8187 | if (!val) | 8187 | if (!val) |
| 8188 | return ira->codegen->invalid_instruction; | 8188 | return ira->codegen->invalid_instruction; |
| 8189 | bool final_is_const = (value->value.type->id == TypeTableEntryIdMetaType) ? is_const : true; | 8189 | bool final_is_const = (value->value.type->id == TypeTableEntryIdMetaType) ? is_const : true; |
| ... | @@ -14931,6 +14931,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio | ... | @@ -14931,6 +14931,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio |
| 14931 | ConstExprValue *parent_ptr; | 14931 | ConstExprValue *parent_ptr; |
| 14932 | size_t abs_offset; | 14932 | size_t abs_offset; |
| 14933 | size_t rel_end; | 14933 | size_t rel_end; |
| | 14934 | bool ptr_is_undef = false; |
| 14934 | if (array_type->id == TypeTableEntryIdArray) { | 14935 | if (array_type->id == TypeTableEntryIdArray) { |
| 14935 | array_val = const_ptr_pointee(ira->codegen, &ptr_ptr->value); | 14936 | array_val = const_ptr_pointee(ira->codegen, &ptr_ptr->value); |
| 14936 | abs_offset = 0; | 14937 | abs_offset = 0; |
| ... | @@ -14938,7 +14939,12 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio | ... | @@ -14938,7 +14939,12 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio |
| 14938 | parent_ptr = nullptr; | 14939 | parent_ptr = nullptr; |
| 14939 | } else if (array_type->id == TypeTableEntryIdPointer) { | 14940 | } else if (array_type->id == TypeTableEntryIdPointer) { |
| 14940 | parent_ptr = const_ptr_pointee(ira->codegen, &ptr_ptr->value); | 14941 | parent_ptr = const_ptr_pointee(ira->codegen, &ptr_ptr->value); |
| 14941 | switch (parent_ptr->data.x_ptr.special) { | 14942 | if (parent_ptr->special == ConstValSpecialUndef) { |
| | 14943 | array_val = nullptr; |
| | 14944 | abs_offset = 0; |
| | 14945 | rel_end = SIZE_MAX; |
| | 14946 | ptr_is_undef = true; |
| | 14947 | } else switch (parent_ptr->data.x_ptr.special) { |
| 14942 | case ConstPtrSpecialInvalid: | 14948 | case ConstPtrSpecialInvalid: |
| 14943 | case ConstPtrSpecialDiscard: | 14949 | case ConstPtrSpecialDiscard: |
| 14944 | zig_unreachable(); | 14950 | zig_unreachable(); |
| ... | @@ -14992,7 +14998,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio | ... | @@ -14992,7 +14998,7 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio |
| 14992 | } | 14998 | } |
| 14993 | | 14999 | |
| 14994 | uint64_t start_scalar = bigint_as_unsigned(&casted_start->value.data.x_bigint); | 15000 | uint64_t start_scalar = bigint_as_unsigned(&casted_start->value.data.x_bigint); |
| 14995 | if (start_scalar > rel_end) { | 15001 | if (!ptr_is_undef && start_scalar > rel_end) { |
| 14996 | ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); | 15002 | ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); |
| 14997 | return ira->codegen->builtin_types.entry_invalid; | 15003 | return ira->codegen->builtin_types.entry_invalid; |
| 14998 | } | 15004 | } |
| ... | @@ -15003,12 +15009,18 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio | ... | @@ -15003,12 +15009,18 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio |
| 15003 | } else { | 15009 | } else { |
| 15004 | end_scalar = rel_end; | 15010 | end_scalar = rel_end; |
| 15005 | } | 15011 | } |
| 15006 | if (end_scalar > rel_end) { | 15012 | if (!ptr_is_undef) { |
| 15007 | ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); | 15013 | if (end_scalar > rel_end) { |
| 15008 | return ira->codegen->builtin_types.entry_invalid; | 15014 | ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); |
| | 15015 | return ira->codegen->builtin_types.entry_invalid; |
| | 15016 | } |
| | 15017 | if (start_scalar > end_scalar) { |
| | 15018 | ir_add_error(ira, &instruction->base, buf_sprintf("slice start is greater than end")); |
| | 15019 | return ira->codegen->builtin_types.entry_invalid; |
| | 15020 | } |
| 15009 | } | 15021 | } |
| 15010 | if (start_scalar > end_scalar) { | 15022 | if (ptr_is_undef && start_scalar != end_scalar) { |
| 15011 | ir_add_error(ira, &instruction->base, buf_sprintf("slice start is greater than end")); | 15023 | ir_add_error(ira, &instruction->base, buf_sprintf("non-zero length slice of undefined pointer")); |
| 15012 | return ira->codegen->builtin_types.entry_invalid; | 15024 | return ira->codegen->builtin_types.entry_invalid; |
| 15013 | } | 15025 | } |
| 15014 | | 15026 | |
| ... | @@ -15024,25 +15036,27 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio | ... | @@ -15024,25 +15036,27 @@ static TypeTableEntry *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructio |
| 15024 | if (array_type->id == TypeTableEntryIdArray) { | 15036 | if (array_type->id == TypeTableEntryIdArray) { |
| 15025 | ptr_val->data.x_ptr.mut = ptr_ptr->value.data.x_ptr.mut; | 15037 | ptr_val->data.x_ptr.mut = ptr_ptr->value.data.x_ptr.mut; |
| 15026 | } | 15038 | } |
| 15027 | } else { | 15039 | } else if (ptr_is_undef) { |
| 15028 | switch (parent_ptr->data.x_ptr.special) { | 15040 | ptr_val->type = get_pointer_to_type(ira->codegen, parent_ptr->type->data.pointer.child_type, |
| 15029 | case ConstPtrSpecialInvalid: | 15041 | slice_is_const(return_type)); |
| 15030 | case ConstPtrSpecialDiscard: | 15042 | ptr_val->special = ConstValSpecialUndef; |
| 15031 | zig_unreachable(); | 15043 | } else switch (parent_ptr->data.x_ptr.special) { |
| 15032 | case ConstPtrSpecialRef: | 15044 | case ConstPtrSpecialInvalid: |
| 15033 | init_const_ptr_ref(ira->codegen, ptr_val, | 15045 | case ConstPtrSpecialDiscard: |
| 15034 | parent_ptr->data.x_ptr.data.ref.pointee, slice_is_const(return_type)); | 15046 | zig_unreachable(); |
| 15035 | break; | 15047 | case ConstPtrSpecialRef: |
| 15036 | case ConstPtrSpecialBaseArray: | 15048 | init_const_ptr_ref(ira->codegen, ptr_val, |
| 15037 | zig_unreachable(); | 15049 | parent_ptr->data.x_ptr.data.ref.pointee, slice_is_const(return_type)); |
| 15038 | case ConstPtrSpecialBaseStruct: | 15050 | break; |
| 15039 | zig_panic("TODO"); | 15051 | case ConstPtrSpecialBaseArray: |
| 15040 | case ConstPtrSpecialHardCodedAddr: | 15052 | zig_unreachable(); |
| 15041 | init_const_ptr_hard_coded_addr(ira->codegen, ptr_val, | 15053 | case ConstPtrSpecialBaseStruct: |
| 15042 | parent_ptr->type->data.pointer.child_type, | 15054 | zig_panic("TODO"); |
| 15043 | parent_ptr->data.x_ptr.data.hard_coded_addr.addr + start_scalar, | 15055 | case ConstPtrSpecialHardCodedAddr: |
| 15044 | slice_is_const(return_type)); | 15056 | init_const_ptr_hard_coded_addr(ira->codegen, ptr_val, |
| 15045 | } | 15057 | parent_ptr->type->data.pointer.child_type, |
| | 15058 | parent_ptr->data.x_ptr.data.hard_coded_addr.addr + start_scalar, |
| | 15059 | slice_is_const(return_type)); |
| 15046 | } | 15060 | } |
| 15047 | | 15061 | |
| 15048 | ConstExprValue *len_val = &out_val->data.x_struct.fields[slice_len_index]; | 15062 | ConstExprValue *len_val = &out_val->data.x_struct.fields[slice_len_index]; |