From f824658e136738ea75c8bb3b53d9a67b2c4402b7 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 19 Mar 2020 10:54:20 -0400 Subject: [PATCH] slicing sentinel-terminated slice without end now results in a sentinel-terminated slice. --- src/ir.cpp | 4 ++ test/stage1/behavior/slice.zig | 79 ++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/src/ir.cpp b/src/ir.cpp index 4800dd910..e20111e21 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -26249,6 +26249,7 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i end = nullptr; } + ZigValue *slice_sentinel_val = nullptr; ZigType *non_sentinel_slice_ptr_type; ZigType *elem_type; @@ -26299,6 +26300,7 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i } } else if (is_slice(array_type)) { ZigType *maybe_sentineled_slice_ptr_type = array_type->data.structure.fields[slice_ptr_index]->type_entry; + slice_sentinel_val = maybe_sentineled_slice_ptr_type->data.pointer.sentinel; non_sentinel_slice_ptr_type = adjust_ptr_sentinel(ira->codegen, maybe_sentineled_slice_ptr_type, nullptr); elem_type = non_sentinel_slice_ptr_type->data.pointer.child_type; } else { @@ -26376,6 +26378,8 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i PtrLenSingle, ptr_byte_alignment, 0, 0, false); goto done_with_return_type; } + } else if (array_sentinel == nullptr && end == nullptr) { + array_sentinel = slice_sentinel_val; } if (array_sentinel != nullptr) { // TODO deal with non-abi-alignment here diff --git a/test/stage1/behavior/slice.zig b/test/stage1/behavior/slice.zig index 26ad8425f..203a3b72d 100644 --- a/test/stage1/behavior/slice.zig +++ b/test/stage1/behavior/slice.zig @@ -130,3 +130,82 @@ test "empty array to slice" { S.doTheTest(); comptime S.doTheTest(); } + +test "@ptrCast slice to pointer" { + const S = struct { + fn doTheTest() void { + var array align(@alignOf(u16)) = [5]u8{ 0xff, 0xff, 0xff, 0xff, 0xff }; + var slice: []u8 = &array; + var ptr = @ptrCast(*u16, slice); + expect(ptr.* == 65535); + } + }; + + S.doTheTest(); + comptime S.doTheTest(); +} + +test "slicing producing an array" { + const S = struct { + fn doTheTest() void { + testArray(); + testArrayZ(); + testPointer(); + testPointerZ(); + testSlice(); + testSliceZ(); + } + + fn testArray() void { + var array = [5]u8{ 1, 2, 3, 4, 5 }; + var slice = array[1..3]; + comptime expect(@TypeOf(slice) == *[2]u8); + expect(slice[0] == 2); + expect(slice[1] == 3); + } + + fn testArrayZ() void { + var array = [5:0]u8{ 1, 2, 3, 4, 5 }; + comptime expect(@TypeOf(array[1..3]) == *[2]u8); + comptime expect(@TypeOf(array[1..5]) == *[4:0]u8); + comptime expect(@TypeOf(array[1..]) == *[4:0]u8); + comptime expect(@TypeOf(array[1..3 :4]) == *[2:4]u8); + } + + fn testPointer() void { + var array = [5]u8{ 1, 2, 3, 4, 5 }; + var pointer: [*]u8 = &array; + var slice = pointer[1..3]; + comptime expect(@TypeOf(slice) == *[2]u8); + expect(slice[0] == 2); + expect(slice[1] == 3); + } + + fn testPointerZ() void { + var array = [5:0]u8{ 1, 2, 3, 4, 5 }; + var pointer: [*:0]u8 = &array; + comptime expect(@TypeOf(pointer[1..3]) == *[2]u8); + comptime expect(@TypeOf(pointer[1..3 :4]) == *[2:4]u8); + } + + fn testSlice() void { + var array = [5]u8{ 1, 2, 3, 4, 5 }; + var src_slice: []u8 = &array; + var slice = src_slice[1..3]; + comptime expect(@TypeOf(slice) == *[2]u8); + expect(slice[0] == 2); + expect(slice[1] == 3); + } + + fn testSliceZ() void { + var array = [5:0]u8{ 1, 2, 3, 4, 5 }; + var slice: [:0]u8 = &array; + comptime expect(@TypeOf(slice[1..3]) == *[2]u8); + comptime expect(@TypeOf(slice[1..]) == [:0]u8); + comptime expect(@TypeOf(slice[1..3 :4]) == *[2:4]u8); + } + }; + + S.doTheTest(); + comptime S.doTheTest(); +}