authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-19 10:54:20-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-19 10:54:20-04:00
logf824658e136738ea75c8bb3b53d9a67b2c4402b7
treeb4dfb95c0146e5d2c8f34110a550e98c2a766609
parent61266d26212e89e97d285eb61416d625303704bc
signaturelock-open Commit is signed but in an unrecognized format.

slicing sentinel-terminated slice without end

now results in a sentinel-terminated slice.

2 files changed, 83 insertions(+), 0 deletions(-)

src/ir.cpp+4
...@@ -26249,6 +26249,7 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i...@@ -26249,6 +26249,7 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
26249 end = nullptr;26249 end = nullptr;
26250 }26250 }
2625126251
26252 ZigValue *slice_sentinel_val = nullptr;
26252 ZigType *non_sentinel_slice_ptr_type;26253 ZigType *non_sentinel_slice_ptr_type;
26253 ZigType *elem_type;26254 ZigType *elem_type;
2625426255
...@@ -26299,6 +26300,7 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i...@@ -26299,6 +26300,7 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
26299 }26300 }
26300 } else if (is_slice(array_type)) {26301 } else if (is_slice(array_type)) {
26301 ZigType *maybe_sentineled_slice_ptr_type = array_type->data.structure.fields[slice_ptr_index]->type_entry;26302 ZigType *maybe_sentineled_slice_ptr_type = array_type->data.structure.fields[slice_ptr_index]->type_entry;
26303 slice_sentinel_val = maybe_sentineled_slice_ptr_type->data.pointer.sentinel;
26302 non_sentinel_slice_ptr_type = adjust_ptr_sentinel(ira->codegen, maybe_sentineled_slice_ptr_type, nullptr);26304 non_sentinel_slice_ptr_type = adjust_ptr_sentinel(ira->codegen, maybe_sentineled_slice_ptr_type, nullptr);
26303 elem_type = non_sentinel_slice_ptr_type->data.pointer.child_type;26305 elem_type = non_sentinel_slice_ptr_type->data.pointer.child_type;
26304 } else {26306 } else {
...@@ -26376,6 +26378,8 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i...@@ -26376,6 +26378,8 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
26376 PtrLenSingle, ptr_byte_alignment, 0, 0, false);26378 PtrLenSingle, ptr_byte_alignment, 0, 0, false);
26377 goto done_with_return_type;26379 goto done_with_return_type;
26378 }26380 }
26381 } else if (array_sentinel == nullptr && end == nullptr) {
26382 array_sentinel = slice_sentinel_val;
26379 }26383 }
26380 if (array_sentinel != nullptr) {26384 if (array_sentinel != nullptr) {
26381 // TODO deal with non-abi-alignment here26385 // TODO deal with non-abi-alignment here
test/stage1/behavior/slice.zig+79
...@@ -130,3 +130,82 @@ test "empty array to slice" {...@@ -130,3 +130,82 @@ test "empty array to slice" {
130 S.doTheTest();130 S.doTheTest();
131 comptime S.doTheTest();131 comptime S.doTheTest();
132}132}
133
134test "@ptrCast slice to pointer" {
135 const S = struct {
136 fn doTheTest() void {
137 var array align(@alignOf(u16)) = [5]u8{ 0xff, 0xff, 0xff, 0xff, 0xff };
138 var slice: []u8 = &array;
139 var ptr = @ptrCast(*u16, slice);
140 expect(ptr.* == 65535);
141 }
142 };
143
144 S.doTheTest();
145 comptime S.doTheTest();
146}
147
148test "slicing producing an array" {
149 const S = struct {
150 fn doTheTest() void {
151 testArray();
152 testArrayZ();
153 testPointer();
154 testPointerZ();
155 testSlice();
156 testSliceZ();
157 }
158
159 fn testArray() void {
160 var array = [5]u8{ 1, 2, 3, 4, 5 };
161 var slice = array[1..3];
162 comptime expect(@TypeOf(slice) == *[2]u8);
163 expect(slice[0] == 2);
164 expect(slice[1] == 3);
165 }
166
167 fn testArrayZ() void {
168 var array = [5:0]u8{ 1, 2, 3, 4, 5 };
169 comptime expect(@TypeOf(array[1..3]) == *[2]u8);
170 comptime expect(@TypeOf(array[1..5]) == *[4:0]u8);
171 comptime expect(@TypeOf(array[1..]) == *[4:0]u8);
172 comptime expect(@TypeOf(array[1..3 :4]) == *[2:4]u8);
173 }
174
175 fn testPointer() void {
176 var array = [5]u8{ 1, 2, 3, 4, 5 };
177 var pointer: [*]u8 = &array;
178 var slice = pointer[1..3];
179 comptime expect(@TypeOf(slice) == *[2]u8);
180 expect(slice[0] == 2);
181 expect(slice[1] == 3);
182 }
183
184 fn testPointerZ() void {
185 var array = [5:0]u8{ 1, 2, 3, 4, 5 };
186 var pointer: [*:0]u8 = &array;
187 comptime expect(@TypeOf(pointer[1..3]) == *[2]u8);
188 comptime expect(@TypeOf(pointer[1..3 :4]) == *[2:4]u8);
189 }
190
191 fn testSlice() void {
192 var array = [5]u8{ 1, 2, 3, 4, 5 };
193 var src_slice: []u8 = &array;
194 var slice = src_slice[1..3];
195 comptime expect(@TypeOf(slice) == *[2]u8);
196 expect(slice[0] == 2);
197 expect(slice[1] == 3);
198 }
199
200 fn testSliceZ() void {
201 var array = [5:0]u8{ 1, 2, 3, 4, 5 };
202 var slice: [:0]u8 = &array;
203 comptime expect(@TypeOf(slice[1..3]) == *[2]u8);
204 comptime expect(@TypeOf(slice[1..]) == [:0]u8);
205 comptime expect(@TypeOf(slice[1..3 :4]) == *[2:4]u8);
206 }
207 };
208
209 S.doTheTest();
210 comptime S.doTheTest();
211}