diff options
| author | Alexandros Naskos <alex_naskos@hotmail.com> | 2020-03-02 00:55:19 +0200 |
|---|---|---|
| committer | Alexandros Naskos <alex_naskos@hotmail.com> | 2020-03-02 00:55:19 +0200 |
| commit | b838122cc0bfef2d986c6addc688a35318777034 (patch) | |
| tree | 2ed5ef3aab4f9fa1f7f0bac2ad28690c3966ddcc /src/ir.cpp | |
| parent | 78e4daaa03613da5d1398f7c3bcbfda24086b051 (diff) | |
| parent | 00be934569d25e3b041091ff63a4cf6c456d1403 (diff) | |
| download | zig-b838122cc0bfef2d986c6addc688a35318777034.tar.gz zig-b838122cc0bfef2d986c6addc688a35318777034.zip | |
Merge branch 'master' of https://github.com/ziglang/zig into tuple_concat
Diffstat (limited to 'src/ir.cpp')
| -rw-r--r-- | src/ir.cpp | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index 977c4b65eb..dd977acd73 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -17829,6 +17829,7 @@ static IrInstGen *ir_analyze_instruction_export(IrAnalyze *ira, IrInstSrcExport } } break; case ZigTypeIdInt: + want_var_export = true; break; case ZigTypeIdVoid: case ZigTypeIdBool: @@ -20399,6 +20400,17 @@ static ZigType *adjust_ptr_len(CodeGen *g, ZigType *ptr_type, PtrLen ptr_len) { ptr_type->data.pointer.allow_zero); } +static ZigType *adjust_ptr_allow_zero(CodeGen *g, ZigType *ptr_type, bool allow_zero) { + assert(ptr_type->id == ZigTypeIdPointer); + return get_pointer_to_type_extra(g, + ptr_type->data.pointer.child_type, + ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, + ptr_type->data.pointer.ptr_len, + ptr_type->data.pointer.explicit_alignment, + ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes, + allow_zero); +} + static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemPtr *elem_ptr_instruction) { Error err; IrInstGen *array_ptr = elem_ptr_instruction->array_ptr->child; @@ -25956,6 +25968,8 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i ZigType *non_sentinel_slice_ptr_type; ZigType *elem_type; + bool generate_non_null_assert = false; + if (array_type->id == ZigTypeIdArray) { elem_type = array_type->data.array.child_type; bool is_comptime_const = ptr_ptr->value->special == ConstValSpecialStatic && @@ -25983,6 +25997,14 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i elem_type = array_type->data.pointer.child_type; if (array_type->data.pointer.ptr_len == PtrLenC) { array_type = adjust_ptr_len(ira->codegen, array_type, PtrLenUnknown); + + // C pointers are allowzero by default. + // However, we want to be able to slice them without generating an allowzero slice (see issue #4401). + // To achieve this, we generate a runtime safety check and make the slice type non-allowzero. + if (array_type->data.pointer.allow_zero) { + array_type = adjust_ptr_allow_zero(ira->codegen, array_type, false); + generate_non_null_assert = true; + } } ZigType *maybe_sentineled_slice_ptr_type = array_type; non_sentinel_slice_ptr_type = adjust_ptr_sentinel(ira->codegen, maybe_sentineled_slice_ptr_type, nullptr); @@ -26254,7 +26276,6 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc, return_type, nullptr, true, true); - if (result_loc != nullptr) { if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) { return result_loc; @@ -26267,8 +26288,17 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i return ira->codegen->invalid_inst_gen; } - return ir_build_slice_gen(ira, &instruction->base.base, return_type, - ptr_ptr, casted_start, end, instruction->safety_check_on, result_loc); + if (generate_non_null_assert) { + IrInstGen *ptr_val = ir_get_deref(ira, &instruction->base.base, ptr_ptr, nullptr); + + if (type_is_invalid(ptr_val->value->type)) + return ira->codegen->invalid_inst_gen; + + ir_build_assert_non_null(ira, &instruction->base.base, ptr_val); + } + + return ir_build_slice_gen(ira, &instruction->base.base, return_type, ptr_ptr, + casted_start, end, instruction->safety_check_on, result_loc); } static IrInstGen *ir_analyze_instruction_has_field(IrAnalyze *ira, IrInstSrcHasField *instruction) { |
