aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorAlexandros Naskos <alex_naskos@hotmail.com>2020-03-02 00:55:19 +0200
committerAlexandros Naskos <alex_naskos@hotmail.com>2020-03-02 00:55:19 +0200
commitb838122cc0bfef2d986c6addc688a35318777034 (patch)
tree2ed5ef3aab4f9fa1f7f0bac2ad28690c3966ddcc /src/ir.cpp
parent78e4daaa03613da5d1398f7c3bcbfda24086b051 (diff)
parent00be934569d25e3b041091ff63a4cf6c456d1403 (diff)
downloadzig-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.cpp36
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) {