| ... | ... | @@ -20412,6 +20412,17 @@ static ZigType *adjust_ptr_len(CodeGen *g, ZigType *ptr_type, PtrLen ptr_len) { |
| 20412 | 20412 | ptr_type->data.pointer.allow_zero); |
| 20413 | 20413 | } |
| 20414 | 20414 | |
| 20415 | static ZigType *adjust_ptr_allow_zero(CodeGen *g, ZigType *ptr_type, bool allow_zero) { |
| 20416 | assert(ptr_type->id == ZigTypeIdPointer); |
| 20417 | return get_pointer_to_type_extra(g, |
| 20418 | ptr_type->data.pointer.child_type, |
| 20419 | ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, |
| 20420 | ptr_type->data.pointer.ptr_len, |
| 20421 | ptr_type->data.pointer.explicit_alignment, |
| 20422 | ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes, |
| 20423 | allow_zero); |
| 20424 | } |
| 20425 | |
| 20415 | 20426 | static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemPtr *elem_ptr_instruction) { |
| 20416 | 20427 | Error err; |
| 20417 | 20428 | IrInstGen *array_ptr = elem_ptr_instruction->array_ptr->child; |
| ... | ... | @@ -25966,6 +25977,8 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i |
| 25966 | 25977 | ZigType *non_sentinel_slice_ptr_type; |
| 25967 | 25978 | ZigType *elem_type; |
| 25968 | 25979 | |
| 25980 | bool generate_non_null_assert = false; |
| 25981 | |
| 25969 | 25982 | if (array_type->id == ZigTypeIdArray) { |
| 25970 | 25983 | elem_type = array_type->data.array.child_type; |
| 25971 | 25984 | bool is_comptime_const = ptr_ptr->value->special == ConstValSpecialStatic && |
| ... | ... | @@ -25993,6 +26006,14 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i |
| 25993 | 26006 | elem_type = array_type->data.pointer.child_type; |
| 25994 | 26007 | if (array_type->data.pointer.ptr_len == PtrLenC) { |
| 25995 | 26008 | array_type = adjust_ptr_len(ira->codegen, array_type, PtrLenUnknown); |
| 26009 | |
| 26010 | // C pointers are allowzero by default. |
| 26011 | // However, we want to be able to slice them without generating an allowzero slice (see issue #4401). |
| 26012 | // To achieve this, we generate a runtime safety check and make the slice type non-allowzero. |
| 26013 | if (array_type->data.pointer.allow_zero) { |
| 26014 | array_type = adjust_ptr_allow_zero(ira->codegen, array_type, false); |
| 26015 | generate_non_null_assert = true; |
| 26016 | } |
| 25996 | 26017 | } |
| 25997 | 26018 | ZigType *maybe_sentineled_slice_ptr_type = array_type; |
| 25998 | 26019 | non_sentinel_slice_ptr_type = adjust_ptr_sentinel(ira->codegen, maybe_sentineled_slice_ptr_type, nullptr); |
| ... | ... | @@ -26264,7 +26285,6 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i |
| 26264 | 26285 | |
| 26265 | 26286 | IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, |
| 26266 | 26287 | return_type, nullptr, true, true); |
| 26267 | | |
| 26268 | 26288 | if (result_loc != nullptr) { |
| 26269 | 26289 | if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { |
| 26270 | 26290 | return result_loc; |
| ... | ... | @@ -26277,8 +26297,17 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i |
| 26277 | 26297 | return ira->codegen->invalid_inst_gen; |
| 26278 | 26298 | } |
| 26279 | 26299 | |
| 26280 | | return ir_build_slice_gen(ira, &instruction->base.base, return_type, |
| 26281 | | ptr_ptr, casted_start, end, instruction->safety_check_on, result_loc); |
| 26300 | if (generate_non_null_assert) { |
| 26301 | IrInstGen *ptr_val = ir_get_deref(ira, &instruction->base.base, ptr_ptr, nullptr); |
| 26302 | |
| 26303 | if (type_is_invalid(ptr_val->value->type)) |
| 26304 | return ira->codegen->invalid_inst_gen; |
| 26305 | |
| 26306 | ir_build_assert_non_null(ira, &instruction->base.base, ptr_val); |
| 26307 | } |
| 26308 | |
| 26309 | return ir_build_slice_gen(ira, &instruction->base.base, return_type, ptr_ptr, |
| 26310 | casted_start, end, instruction->safety_check_on, result_loc); |
| 26282 | 26311 | } |
| 26283 | 26312 | |
| 26284 | 26313 | static IrInstGen *ir_analyze_instruction_has_field(IrAnalyze *ira, IrInstSrcHasField *instruction) { |