Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slice fixes #21426

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
8 changes: 8 additions & 0 deletions lib/std/builtin.zig
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,14 @@ pub fn panicInactiveUnionField(active: anytype, wanted: @TypeOf(active)) noretur
std.debug.panicExtra(null, @returnAddress(), "access of union field '{s}' while field '{s}' is active", .{ @tagName(wanted), @tagName(active) });
}

pub fn panicStartGreaterThanEndExtra(start: usize, end: usize, len: usize) noreturn {
@branchHint(.cold);
if (start > end)
std.debug.panicExtra(null, @returnAddress(), "start index {d} is larger than end index {d}", .{ start, end })
else
std.debug.panicExtra(null, @returnAddress(), "index out of bounds: index {d}, len {d}", .{ end, len });
}

pub const panic_messages = struct {
pub const unreach = "reached unreachable code";
pub const unwrap_null = "attempt to use null value";
Expand Down
2 changes: 1 addition & 1 deletion lib/std/multi_array_list.zig
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ pub fn MultiArrayList(comptime T: type) type {
}
const byte_ptr = self.ptrs[@intFromEnum(field)];
const casted_ptr: [*]F = if (@sizeOf(F) == 0)
undefined
&[_]F{}
else
@ptrCast(@alignCast(byte_ptr));
return casted_ptr[0..self.len];
Expand Down
2 changes: 1 addition & 1 deletion lib/std/tz.zig
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ pub const Tz = struct {
timetypes[i] = .{
.offset = offset,
.flags = dst,
.name_data = undefined,
.name_data = .{0} ** 6,
};

// Temporarily cache idx in name_data to be processed after we've read the designator names below
Expand Down
1,406 changes: 847 additions & 559 deletions src/Sema.zig

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion test/behavior/comptime_memory.zig
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ test "type pun signed and unsigned as array pointer with pointer arithemtic" {
comptime {
var x: [11]u32 = undefined;
const y = @as([*]i32, @ptrCast(&x[10])) - 10;
const z: *[15]i32 = y[0..15];
const z: *[11]i32 = y[0..11];
z[10] = -1;
try testing.expectEqual(@as(u32, 0xFFFFFFFF), x[10]);
}
Expand Down
12 changes: 10 additions & 2 deletions test/behavior/slice.zig
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ test "comptime slice of undefined pointer of length 0" {
try expect(slice1.len == 0);
const slice2 = @as([*]i32, undefined)[100..100];
try expect(slice2.len == 0);
const slice3 = @as(*[0]u8, undefined)[0..0];
try expect(slice3.len == 0);
const slice4 = @as(*u8, undefined)[0..0];
try expect(slice4.len == 0);
const slice5 = @as([*c]u8, undefined)[0..0];
try expect(slice5.len == 0);
const slice6 = @as([]u8, undefined)[0..0];
try expect(slice6.len == 0);
}

test "implicitly cast array of size 0 to slice" {
Expand Down Expand Up @@ -378,11 +386,11 @@ test "slice multi-pointer without end" {
var array = [5:0]u8{ 1, 2, 3, 4, 5 };
const pointer: [*:0]u8 = &array;

comptime assert(@TypeOf(pointer[1..]) == [*:0]u8);
comptime assert(@TypeOf(pointer[1..]) == [*]u8);
comptime assert(@TypeOf(pointer[1.. :0]) == [*:0]u8);

const slice = pointer[1..];
comptime assert(@TypeOf(slice) == [*:0]u8);
comptime assert(@TypeOf(slice) == [*]u8);
try expect(slice[0] == 2);
try expect(slice[1] == 3);
}
Expand Down
2 changes: 1 addition & 1 deletion test/behavior/slice_sentinel_comptime.zig
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ test "comptime slice-sentinel in bounds (on target sentinel)" {
// slice
comptime {
var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
var target: []u8 = &buf;
var target: []u8 = buf[0..15];
const slice = target[0..14 :0];
_ = slice;
}
Expand Down
2 changes: 1 addition & 1 deletion test/behavior/void.zig
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ test "iterate over a void slice" {
}

fn times(n: usize) []const void {
return @as([*]void, undefined)[0..n];
return @as([*]void, &[_]void{})[0..n];
}

test "void optional" {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,17 @@ export fn foo_slice() void {
// backend=stage2
// target=native
//
// :4:29: error: value in memory does not match slice sentinel
// :4:29: note: expected '0', found '100'
// :12:29: error: value in memory does not match slice sentinel
// :12:29: note: expected '0', found '100'
// :20:29: error: value in memory does not match slice sentinel
// :20:29: note: expected '0', found '100'
// :28:29: error: value in memory does not match slice sentinel
// :28:29: note: expected '0', found '100'
// :36:29: error: value in memory does not match slice sentinel
// :36:29: note: expected '0', found '100'
// :44:29: error: value in memory does not match slice sentinel
// :44:29: note: expected '0', found '100'
// :52:29: error: value in memory does not match slice sentinel
// :52:29: note: expected '0', found '100'
// :4:36: error: value in memory does not match slice sentinel
// :4:36: note: expected '0', found '100'
// :12:36: error: value in memory does not match slice sentinel
// :12:36: note: expected '0', found '100'
// :20:36: error: value in memory does not match slice sentinel
// :20:36: note: expected '0', found '100'
// :28:36: error: value in memory does not match slice sentinel
// :28:36: note: expected '0', found '100'
// :36:36: error: value in memory does not match slice sentinel
// :36:36: note: expected '0', found '100'
// :44:36: error: value in memory does not match slice sentinel
// :44:36: note: expected '0', found '100'
// :52:36: error: value in memory does not match slice sentinel
// :52:36: note: expected '0', found '100'
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,17 @@ export fn foo_slice() void {
// backend=stage2
// target=native
//
// :4:29: error: value in memory does not match slice sentinel
// :4:29: note: expected '0', found '100'
// :12:29: error: value in memory does not match slice sentinel
// :12:29: note: expected '0', found '100'
// :20:29: error: value in memory does not match slice sentinel
// :20:29: note: expected '0', found '100'
// :28:29: error: value in memory does not match slice sentinel
// :28:29: note: expected '0', found '100'
// :36:29: error: value in memory does not match slice sentinel
// :36:29: note: expected '0', found '100'
// :44:29: error: value in memory does not match slice sentinel
// :44:29: note: expected '0', found '100'
// :52:29: error: value in memory does not match slice sentinel
// :52:29: note: expected '0', found '100'
// :4:36: error: value in memory does not match slice sentinel
// :4:36: note: expected '0', found '100'
// :12:36: error: value in memory does not match slice sentinel
// :12:36: note: expected '0', found '100'
// :20:36: error: value in memory does not match slice sentinel
// :20:36: note: expected '0', found '100'
// :28:36: error: value in memory does not match slice sentinel
// :28:36: note: expected '0', found '100'
// :36:36: error: value in memory does not match slice sentinel
// :36:36: note: expected '0', found '100'
// :44:36: error: value in memory does not match slice sentinel
// :44:36: note: expected '0', found '100'
// :52:36: error: value in memory does not match slice sentinel
// :52:36: note: expected '0', found '100'
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export fn foo_cvector_ConstPtrSpecialRef() void {
export fn foo_slice() void {
comptime {
var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
var target: []u8 = &buf;
var target: [:0]u8 = &buf;
const slice = target[0..14 :255];
_ = slice;
}
Expand All @@ -73,23 +73,23 @@ export fn typeName_slice() void {
// backend=stage2
// target=native
//
// :4:29: error: value in memory does not match slice sentinel
// :4:29: note: expected '255', found '0'
// :12:29: error: value in memory does not match slice sentinel
// :12:29: note: expected '255', found '0'
// :20:29: error: value in memory does not match slice sentinel
// :20:29: note: expected '255', found '0'
// :28:29: error: value in memory does not match slice sentinel
// :28:29: note: expected '255', found '0'
// :36:29: error: value in memory does not match slice sentinel
// :36:29: note: expected '255', found '0'
// :44:29: error: value in memory does not match slice sentinel
// :44:29: note: expected '255', found '0'
// :52:29: error: value in memory does not match slice sentinel
// :52:29: note: expected '255', found '0'
// :58:22: error: value in memory does not match slice sentinel
// :58:22: note: expected '0', found 'undefined'
// :63:22: error: value in memory does not match slice sentinel
// :63:22: note: expected '12', found '98'
// :68:22: error: value in memory does not match slice sentinel
// :68:22: note: expected '0', found '105'
// :4:37: error: value in memory does not match slice sentinel
// :4:37: note: expected '255', found '0'
// :12:37: error: value in memory does not match slice sentinel
// :12:37: note: expected '255', found '0'
// :20:37: error: value in memory does not match slice sentinel
// :20:37: note: expected '255', found '0'
// :28:37: error: value in memory does not match slice sentinel
// :28:37: note: expected '255', found '0'
// :36:37: error: value in memory does not match slice sentinel
// :36:37: note: expected '255', found '0'
// :44:37: error: value in memory does not match slice sentinel
// :44:37: note: expected '255', found '0'
// :52:37: error: value in memory does not match slice sentinel
// :52:37: note: expected '255', found '0'
// :58:30: error: value in memory does not match slice sentinel
// :58:30: note: expected '0', found 'undefined'
// :63:29: error: value in memory does not match slice sentinel
// :63:29: note: expected '12', found '98'
// :68:29: error: value in memory does not match slice sentinel
// :68:29: note: expected '0', found '105'
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,14 @@ export fn foo_slice() void {
// backend=stage2
// target=native
//
// :4:33: error: slice end index 15 exceeds bounds of containing decl of type '[14:0]u8'
// :12:33: error: slice end index 15 exceeds bounds of containing decl of type '[14:0]u8'
// :20:33: error: slice end index 15 exceeds bounds of containing decl of type '[14:0]u8'
// :28:33: error: slice end index 15 exceeds bounds of containing decl of type '[14:0]u8'
// :36:33: error: slice end index 15 exceeds bounds of containing decl of type '[14:0]u8'
// :44:33: error: slice end index 15 exceeds bounds of containing decl of type '[14:0]u8'
// :52:33: error: end index 15 out of bounds for slice of length 14
// :4:33: error: slice end index out of bounds: end 15, length 14
// :12:33: error: slice end index out of bounds: end 15, length 14
// :20:37: error: slice sentinel index out of bounds: index 15
// :20:37: note: containing decl of type '[14:0]u8'
// :28:37: error: slice sentinel index out of bounds: index 15
// :28:37: note: containing decl of type '[14:0]u8'
// :36:37: error: slice sentinel index out of bounds: index 15
// :36:37: note: containing decl of type '[14:0]u8'
// :44:37: error: slice sentinel index out of bounds: index 15
// :44:37: note: containing decl of type '[14:0]u8'
// :52:33: error: slice end index out of bounds: end 15, length 14
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,14 @@ export fn foo_slice() void {
// backend=stage2
// target=native
//
// :4:33: error: slice end index 14 exceeds bounds of containing decl of type '[14]u8'
// :12:33: error: slice end index 14 exceeds bounds of containing decl of type '[14]u8'
// :20:33: error: slice end index 14 exceeds bounds of containing decl of type '[14]u8'
// :28:33: error: slice end index 14 exceeds bounds of containing decl of type '[14]u8'
// :36:33: error: slice end index 14 exceeds bounds of containing decl of type '[14]u8'
// :44:33: error: slice end index 14 exceeds bounds of containing decl of type '[14]u8'
// :52:33: error: slice end index 14 exceeds bounds of containing decl of type '[14]u8'
// :4:37: error: slice sentinel index out of bounds: index 14, length 14
// :12:37: error: slice sentinel index out of bounds: index 14, length 14
// :20:37: error: slice sentinel index out of bounds: index 14
// :20:37: note: containing decl of type '[14]u8'
// :28:37: error: slice sentinel index out of bounds: index 14
// :28:37: note: containing decl of type '[14]u8'
// :36:37: error: slice sentinel index out of bounds: index 14
// :36:37: note: containing decl of type '[14]u8'
// :44:37: error: slice sentinel index out of bounds: index 14
// :44:37: note: containing decl of type '[14]u8'
// :52:37: error: slice sentinel index out of bounds: index 14, length 14
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ comptime {
// backend=stage2
// target=native
//
// :3:14: error: slice of undefined
// :3:14: error: non-zero length slice of undefined pointer
15 changes: 0 additions & 15 deletions test/cases/compile_errors/destructure_error_union.zig

This file was deleted.

8 changes: 4 additions & 4 deletions test/cases/compile_errors/out_of_bounds_index.zig
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ comptime {
// error
// target=native
//
// :4:32: error: end index 6 out of bounds for slice of length 4 +1 (sentinel)
// :9:28: error: end index 6 out of bounds for array of length 4 +1 (sentinel)
// :14:28: error: end index 5 out of bounds for array of length 4
// :19:25: error: start index 3 is larger than end index 2
// :4:32: error: slice end index out of bounds: end 6, length 4(+1)
// :9:28: error: slice end index out of bounds: end 6, length 4(+1)
// :14:28: error: slice end index out of bounds: end 5, length 4
// :19:25: error: slice bounds out of order: start 3, end 2
9 changes: 9 additions & 0 deletions test/cases/compile_errors/sentinel_always_out_of_bounds.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export fn entry() void {
var buf: [256]u8 = undefined;
var slice: []u8 = &buf;
_ = slice[0.. :0];
}

// error
//
// :4:20: error: slice sentinel index always out of bounds
2 changes: 1 addition & 1 deletion test/cases/compile_errors/slice_of_null_pointer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ comptime {
// error
// target=native
//
// :5:10: error: slice of null pointer
// :5:9: error: slice of null pointer
15 changes: 5 additions & 10 deletions test/cases/compile_errors/slice_of_single-item_pointer_bounds.zig
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,8 @@ export fn entry2() void {

// error
//
// :5:12: error: slice of single-item pointer must have comptime-known bounds [0..0], [0..1], or [1..1]
// :9:13: error: slice of single-item pointer must have comptime-known bounds [0..0], [0..1], or [1..1]
// :9:13: note: expected '0', found '1'
// :13:16: error: slice of single-item pointer must have comptime-known bounds [0..0], [0..1], or [1..1]
// :13:16: note: expected '1', found '2'
// :17:16: error: end index 2 out of bounds for slice of single-item pointer
// :23:13: error: unable to resolve comptime value
// :23:13: note: slice of single-item pointer must have comptime-known bounds [0..0], [0..1], or [1..1]
// :29:16: error: unable to resolve comptime value
// :29:16: note: slice of single-item pointer must have comptime-known bounds [0..0], [0..1], or [1..1]
// :9:16: error: slice end index out of bounds: end 2, length 1
// :13:16: error: slice end index out of bounds: end 2, length 1
// :17:16: error: slice end index out of bounds: end 2, length 1
// :23:13: error: start index of slice of single-item pointer must be comptime-known
// :29:16: error: end index of slice of single-item pointer must be comptime-known
28 changes: 28 additions & 0 deletions test/cases/compile_errors/slice_undefined.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
var end: usize = 1;
comptime {
_ = @as(*[0:1]u8, undefined)[1..];
}
comptime {
_ = @as([*]u8, undefined)[0..1];
}
comptime {
_ = @as([*]u8, undefined)[0..end];
}
comptime {
_ = @as([]u8, undefined)[0..end];
}
comptime {
_ = @as(*[0]u8, undefined)[0..end :0];
}
comptime {
_ = @as([]u8, &.{})[0..1];
}

// error
//
// :3:33: error: non-zero length slice of undefined pointer
// :6:30: error: non-zero length slice of undefined pointer
// :9:30: error: slice of undefined pointer with runtime length causes undefined behaviour
// :12:29: error: slice of undefined pointer with runtime length causes undefined behaviour
// :15:31: error: sentinel not allowed for slice of undefined pointer
// :18:28: error: slice end index out of bounds: end 1, length 0
7 changes: 0 additions & 7 deletions test/cases/errdefer_discard.zig

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const std = @import("std");

pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
_ = stack_trace;
if (std.mem.eql(u8, message, "index out of bounds: index 1, len 0")) {
if (std.mem.eql(u8, message, "index out of bounds: index 0, len 0")) {
std.process.exit(0);
}
std.process.exit(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const std = @import("std");

pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
_ = stack_trace;
if (std.mem.eql(u8, message, "index out of bounds: index 5, len 4")) {
if (std.mem.eql(u8, message, "index out of bounds: index 4, len 4")) {
std.process.exit(0);
}
std.process.exit(1);
Expand Down
2 changes: 1 addition & 1 deletion test/cases/safety/slice with sentinel out of bounds.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const std = @import("std");

pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
_ = stack_trace;
if (std.mem.eql(u8, message, "index out of bounds: index 5, len 4")) {
if (std.mem.eql(u8, message, "index out of bounds: index 4, len 4")) {
std.process.exit(0);
}
std.process.exit(1);
Expand Down
Loading