authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-28 22:21:49+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-30 11:07:37+03:00
log02dc0732604236a57b43b9612d9b0571f06f905a
treedc20d0b237f86761fb636d2238ceddf92493024f
parentd26d696ee01d3a17d17cde24c8841e7f551ba5f2

Sema: check comptime slice sentinel


13 files changed, 450 insertions(+), 359 deletions(-)

src/Sema.zig+83-13
...@@ -25150,7 +25150,10 @@ fn analyzeSlice(...@@ -25150,7 +25150,10 @@ fn analyzeSlice(
25150 if (!end_is_len) {25150 if (!end_is_len) {
25151 const end = try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);25151 const end = try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);
25152 if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| {25152 if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| {
25153 if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| {25153 if (try sema.resolveMaybeUndefVal(block, src, ptr_or_slice)) |slice_val| {
25154 if (slice_val.isUndef()) {
25155 return sema.fail(block, src, "slice of undefined", .{});
25156 }
25154 const has_sentinel = slice_ty.sentinel() != null;25157 const has_sentinel = slice_ty.sentinel() != null;
25155 var int_payload: Value.Payload.U64 = .{25158 var int_payload: Value.Payload.U64 = .{
25156 .base = .{ .tag = .int_u64 },25159 .base = .{ .tag = .int_u64 },
...@@ -25213,8 +25216,8 @@ fn analyzeSlice(...@@ -25213,8 +25216,8 @@ fn analyzeSlice(
25213 };25216 };
2521425217
25215 // requirement: start <= end25218 // requirement: start <= end
25216 if (try sema.resolveDefinedValue(block, src, end)) |end_val| {25219 if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| {
25217 if (try sema.resolveDefinedValue(block, src, start)) |start_val| {25220 if (try sema.resolveDefinedValue(block, start_src, start)) |start_val| {
25218 if (try sema.compare(block, src, start_val, .gt, end_val, Type.usize)) {25221 if (try sema.compare(block, src, start_val, .gt, end_val, Type.usize)) {
25219 return sema.fail(25222 return sema.fail(
25220 block,25223 block,
...@@ -25226,6 +25229,45 @@ fn analyzeSlice(...@@ -25226,6 +25229,45 @@ fn analyzeSlice(
25226 },25229 },
25227 );25230 );
25228 }25231 }
25232 if (try sema.resolveMaybeUndefVal(block, ptr_src, new_ptr)) |ptr_val| sentinel_check: {
25233 const expected_sentinel = sentinel orelse break :sentinel_check;
25234 const start_int = start_val.getUnsignedInt(sema.mod.getTarget()).?;
25235 const end_int = end_val.getUnsignedInt(sema.mod.getTarget()).?;
25236 const sentinel_index = try sema.usizeCast(block, end_src, end_int - start_int);
25237
25238 const elem_ptr = try ptr_val.elemPtr(sema.typeOf(new_ptr), sema.arena, sentinel_index, sema.mod);
25239 const res = try sema.pointerDerefExtra(block, src, elem_ptr, elem_ty, false);
25240 const actual_sentinel = switch (res) {
25241 .runtime_load => break :sentinel_check,
25242 .val => |v| v,
25243 .needed_well_defined => |ty| return sema.fail(
25244 block,
25245 src,
25246 "comptime dereference requires '{}' to have a well-defined layout, but it does not.",
25247 .{ty.fmt(sema.mod)},
25248 ),
25249 .out_of_bounds => |ty| return sema.fail(
25250 block,
25251 end_src,
25252 "slice end index {d} exceeds bounds of containing decl of type '{}'",
25253 .{ end_int, ty.fmt(sema.mod) },
25254 ),
25255 };
25256
25257 if (!actual_sentinel.eql(expected_sentinel, elem_ty, sema.mod)) {
25258 const msg = msg: {
25259 const msg = try sema.errMsg(block, src, "value in memory does not match slice sentinel", .{});
25260 errdefer msg.destroy(sema.gpa);
25261 try sema.errNote(block, src, msg, "expected '{}', found '{}'", .{
25262 expected_sentinel.fmtValue(elem_ty, sema.mod),
25263 actual_sentinel.fmtValue(elem_ty, sema.mod),
25264 });
25265
25266 break :msg msg;
25267 };
25268 return sema.failWithOwnedErrorMsg(block, msg);
25269 }
25270 }
25229 }25271 }
25230 }25272 }
2523125273
...@@ -27866,9 +27908,36 @@ pub fn analyzeAddrspace(...@@ -27866,9 +27908,36 @@ pub fn analyzeAddrspace(
27866/// Returns `null` if the pointer contents cannot be loaded at comptime.27908/// Returns `null` if the pointer contents cannot be loaded at comptime.
27867fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr_ty: Type) CompileError!?Value {27909fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr_ty: Type) CompileError!?Value {
27868 const load_ty = ptr_ty.childType();27910 const load_ty = ptr_ty.childType();
27911 const res = try sema.pointerDerefExtra(block, src, ptr_val, load_ty, true);
27912 switch (res) {
27913 .runtime_load => return null,
27914 .val => |v| return v,
27915 .needed_well_defined => |ty| return sema.fail(
27916 block,
27917 src,
27918 "comptime dereference requires '{}' to have a well-defined layout, but it does not.",
27919 .{ty.fmt(sema.mod)},
27920 ),
27921 .out_of_bounds => |ty| return sema.fail(
27922 block,
27923 src,
27924 "dereference of '{}' exceeds bounds of containing decl of type '{}'",
27925 .{ ptr_ty.fmt(sema.mod), ty.fmt(sema.mod) },
27926 ),
27927 }
27928}
27929
27930const DerefResult = union(enum) {
27931 runtime_load,
27932 val: Value,
27933 needed_well_defined: Type,
27934 out_of_bounds: Type,
27935};
27936
27937fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, load_ty: Type, want_mutable: bool) CompileError!DerefResult {
27869 const target = sema.mod.getTarget();27938 const target = sema.mod.getTarget();
27870 const deref = sema.beginComptimePtrLoad(block, src, ptr_val, load_ty) catch |err| switch (err) {27939 const deref = sema.beginComptimePtrLoad(block, src, ptr_val, load_ty) catch |err| switch (err) {
27871 error.RuntimeLoad => return null,27940 error.RuntimeLoad => return DerefResult{ .runtime_load = {} },
27872 else => |e| return e,27941 else => |e| return e,
27873 };27942 };
2787427943
...@@ -27879,39 +27948,40 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr...@@ -27879,39 +27948,40 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr
27879 if (coerce_in_mem_ok) {27948 if (coerce_in_mem_ok) {
27880 // We have a Value that lines up in virtual memory exactly with what we want to load,27949 // We have a Value that lines up in virtual memory exactly with what we want to load,
27881 // and it is in-memory coercible to load_ty. It may be returned without modifications.27950 // and it is in-memory coercible to load_ty. It may be returned without modifications.
27882 if (deref.is_mutable) {27951 if (deref.is_mutable and want_mutable) {
27883 // The decl whose value we are obtaining here may be overwritten with27952 // The decl whose value we are obtaining here may be overwritten with
27884 // a different value upon further semantic analysis, which would27953 // a different value upon further semantic analysis, which would
27885 // invalidate this memory. So we must copy here.27954 // invalidate this memory. So we must copy here.
27886 return try tv.val.copy(sema.arena);27955 return DerefResult{ .val = try tv.val.copy(sema.arena) };
27887 }27956 }
27888 return tv.val;27957 return DerefResult{ .val = tv.val };
27889 }27958 }
27890 }27959 }
2789127960
27892 // The type is not in-memory coercible or the direct dereference failed, so it must27961 // The type is not in-memory coercible or the direct dereference failed, so it must
27893 // be bitcast according to the pointer type we are performing the load through.27962 // be bitcast according to the pointer type we are performing the load through.
27894 if (!load_ty.hasWellDefinedLayout())27963 if (!load_ty.hasWellDefinedLayout()) {
27895 return sema.fail(block, src, "comptime dereference requires '{}' to have a well-defined layout, but it does not.", .{load_ty.fmt(sema.mod)});27964 return DerefResult{ .needed_well_defined = load_ty };
27965 }
2789627966
27897 const load_sz = try sema.typeAbiSize(block, src, load_ty);27967 const load_sz = try sema.typeAbiSize(block, src, load_ty);
2789827968
27899 // Try the smaller bit-cast first, since that's more efficient than using the larger `parent`27969 // Try the smaller bit-cast first, since that's more efficient than using the larger `parent`
27900 if (deref.pointee) |tv| if (load_sz <= try sema.typeAbiSize(block, src, tv.ty))27970 if (deref.pointee) |tv| if (load_sz <= try sema.typeAbiSize(block, src, tv.ty))
27901 return try sema.bitCastVal(block, src, tv.val, tv.ty, load_ty, 0);27971 return DerefResult{ .val = try sema.bitCastVal(block, src, tv.val, tv.ty, load_ty, 0) };
2790227972
27903 // If that fails, try to bit-cast from the largest parent value with a well-defined layout27973 // If that fails, try to bit-cast from the largest parent value with a well-defined layout
27904 if (deref.parent) |parent| if (load_sz + parent.byte_offset <= try sema.typeAbiSize(block, src, parent.tv.ty))27974 if (deref.parent) |parent| if (load_sz + parent.byte_offset <= try sema.typeAbiSize(block, src, parent.tv.ty))
27905 return try sema.bitCastVal(block, src, parent.tv.val, parent.tv.ty, load_ty, parent.byte_offset);27975 return DerefResult{ .val = try sema.bitCastVal(block, src, parent.tv.val, parent.tv.ty, load_ty, parent.byte_offset) };
2790627976
27907 if (deref.ty_without_well_defined_layout) |bad_ty| {27977 if (deref.ty_without_well_defined_layout) |bad_ty| {
27908 // We got no parent for bit-casting, or the parent we got was too small. Either way, the problem27978 // We got no parent for bit-casting, or the parent we got was too small. Either way, the problem
27909 // is that some type we encountered when de-referencing does not have a well-defined layout.27979 // is that some type we encountered when de-referencing does not have a well-defined layout.
27910 return sema.fail(block, src, "comptime dereference requires '{}' to have a well-defined layout, but it does not.", .{bad_ty.fmt(sema.mod)});27980 return DerefResult{ .needed_well_defined = bad_ty };
27911 } else {27981 } else {
27912 // If all encountered types had well-defined layouts, the parent is the root decl and it just27982 // If all encountered types had well-defined layouts, the parent is the root decl and it just
27913 // wasn't big enough for the load.27983 // wasn't big enough for the load.
27914 return sema.fail(block, src, "dereference of '{}' exceeds bounds of containing decl of type '{}'", .{ ptr_ty.fmt(sema.mod), deref.parent.?.tv.ty.fmt(sema.mod) });27984 return DerefResult{ .out_of_bounds = deref.parent.?.tv.ty };
27915 }27985 }
27916}27986}
2791727987
test/cases/compile_errors/comptime_slice-sentinel_does_not_match_memory_at_target_index_terminated.zig created+74
...@@ -0,0 +1,74 @@
1export fn foo_array() void {
2 comptime {
3 var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
4 const slice = target[0..3 :0];
5 _ = slice;
6 }
7}
8export fn foo_ptr_array() void {
9 comptime {
10 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
11 var target = &buf;
12 const slice = target[0..3 :0];
13 _ = slice;
14 }
15}
16export fn foo_vector_ConstPtrSpecialBaseArray() void {
17 comptime {
18 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
19 var target: [*]u8 = &buf;
20 const slice = target[0..3 :0];
21 _ = slice;
22 }
23}
24export fn foo_vector_ConstPtrSpecialRef() void {
25 comptime {
26 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
27 var target: [*]u8 = @ptrCast([*]u8, &buf);
28 const slice = target[0..3 :0];
29 _ = slice;
30 }
31}
32export fn foo_cvector_ConstPtrSpecialBaseArray() void {
33 comptime {
34 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
35 var target: [*c]u8 = &buf;
36 const slice = target[0..3 :0];
37 _ = slice;
38 }
39}
40export fn foo_cvector_ConstPtrSpecialRef() void {
41 comptime {
42 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
43 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
44 const slice = target[0..3 :0];
45 _ = slice;
46 }
47}
48export fn foo_slice() void {
49 comptime {
50 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
51 var target: []u8 = &buf;
52 const slice = target[0..3 :0];
53 _ = slice;
54 }
55}
56
57// error
58// backend=stage2
59// target=native
60//
61// :4:29: error: value in memory does not match slice sentinel
62// :4:29: note: expected '0', found '100'
63// :12:29: error: value in memory does not match slice sentinel
64// :12:29: note: expected '0', found '100'
65// :20:29: error: value in memory does not match slice sentinel
66// :20:29: note: expected '0', found '100'
67// :28:29: error: value in memory does not match slice sentinel
68// :28:29: note: expected '0', found '100'
69// :36:29: error: value in memory does not match slice sentinel
70// :36:29: note: expected '0', found '100'
71// :44:29: error: value in memory does not match slice sentinel
72// :44:29: note: expected '0', found '100'
73// :52:29: error: value in memory does not match slice sentinel
74// :52:29: note: expected '0', found '100'
test/cases/compile_errors/comptime_slice-sentinel_does_not_match_memory_at_target_index_unterminated.zig created+74
...@@ -0,0 +1,74 @@
1export fn foo_array() void {
2 comptime {
3 var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
4 const slice = target[0..3 :0];
5 _ = slice;
6 }
7}
8export fn foo_ptr_array() void {
9 comptime {
10 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
11 var target = &buf;
12 const slice = target[0..3 :0];
13 _ = slice;
14 }
15}
16export fn foo_vector_ConstPtrSpecialBaseArray() void {
17 comptime {
18 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
19 var target: [*]u8 = &buf;
20 const slice = target[0..3 :0];
21 _ = slice;
22 }
23}
24export fn foo_vector_ConstPtrSpecialRef() void {
25 comptime {
26 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
27 var target: [*]u8 = @ptrCast([*]u8, &buf);
28 const slice = target[0..3 :0];
29 _ = slice;
30 }
31}
32export fn foo_cvector_ConstPtrSpecialBaseArray() void {
33 comptime {
34 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
35 var target: [*c]u8 = &buf;
36 const slice = target[0..3 :0];
37 _ = slice;
38 }
39}
40export fn foo_cvector_ConstPtrSpecialRef() void {
41 comptime {
42 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
43 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
44 const slice = target[0..3 :0];
45 _ = slice;
46 }
47}
48export fn foo_slice() void {
49 comptime {
50 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
51 var target: []u8 = &buf;
52 const slice = target[0..3 :0];
53 _ = slice;
54 }
55}
56
57// error
58// backend=stage2
59// target=native
60//
61// :4:29: error: value in memory does not match slice sentinel
62// :4:29: note: expected '0', found '100'
63// :12:29: error: value in memory does not match slice sentinel
64// :12:29: note: expected '0', found '100'
65// :20:29: error: value in memory does not match slice sentinel
66// :20:29: note: expected '0', found '100'
67// :28:29: error: value in memory does not match slice sentinel
68// :28:29: note: expected '0', found '100'
69// :36:29: error: value in memory does not match slice sentinel
70// :36:29: note: expected '0', found '100'
71// :44:29: error: value in memory does not match slice sentinel
72// :44:29: note: expected '0', found '100'
73// :52:29: error: value in memory does not match slice sentinel
74// :52:29: note: expected '0', found '100'
test/cases/compile_errors/comptime_slice-sentinel_does_not_match_target-sentinel.zig created+74
...@@ -0,0 +1,74 @@
1export fn foo_array() void {
2 comptime {
3 var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
4 const slice = target[0..14 :255];
5 _ = slice;
6 }
7}
8export fn foo_ptr_array() void {
9 comptime {
10 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
11 var target = &buf;
12 const slice = target[0..14 :255];
13 _ = slice;
14 }
15}
16export fn foo_vector_ConstPtrSpecialBaseArray() void {
17 comptime {
18 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
19 var target: [*]u8 = &buf;
20 const slice = target[0..14 :255];
21 _ = slice;
22 }
23}
24export fn foo_vector_ConstPtrSpecialRef() void {
25 comptime {
26 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
27 var target: [*]u8 = @ptrCast([*]u8, &buf);
28 const slice = target[0..14 :255];
29 _ = slice;
30 }
31}
32export fn foo_cvector_ConstPtrSpecialBaseArray() void {
33 comptime {
34 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
35 var target: [*c]u8 = &buf;
36 const slice = target[0..14 :255];
37 _ = slice;
38 }
39}
40export fn foo_cvector_ConstPtrSpecialRef() void {
41 comptime {
42 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
43 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
44 const slice = target[0..14 :255];
45 _ = slice;
46 }
47}
48export fn foo_slice() void {
49 comptime {
50 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
51 var target: []u8 = &buf;
52 const slice = target[0..14 :255];
53 _ = slice;
54 }
55}
56
57// error
58// backend=stage2
59// target=native
60//
61// :4:29: error: value in memory does not match slice sentinel
62// :4:29: note: expected '255', found '0'
63// :12:29: error: value in memory does not match slice sentinel
64// :12:29: note: expected '255', found '0'
65// :20:29: error: value in memory does not match slice sentinel
66// :20:29: note: expected '255', found '0'
67// :28:29: error: value in memory does not match slice sentinel
68// :28:29: note: expected '255', found '0'
69// :36:29: error: value in memory does not match slice sentinel
70// :36:29: note: expected '255', found '0'
71// :44:29: error: value in memory does not match slice sentinel
72// :44:29: note: expected '255', found '0'
73// :52:29: error: value in memory does not match slice sentinel
74// :52:29: note: expected '255', found '0'
test/cases/compile_errors/comptime_slice-sentinel_is_out_of_bounds_terminated.zig created+67
...@@ -0,0 +1,67 @@
1export fn foo_array() void {
2 comptime {
3 var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
4 const slice = target[0..15 :1];
5 _ = slice;
6 }
7}
8export fn foo_ptr_array() void {
9 comptime {
10 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
11 var target = &buf;
12 const slice = target[0..15 :0];
13 _ = slice;
14 }
15}
16export fn foo_vector_ConstPtrSpecialBaseArray() void {
17 comptime {
18 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
19 var target: [*]u8 = &buf;
20 const slice = target[0..15 :0];
21 _ = slice;
22 }
23}
24export fn foo_vector_ConstPtrSpecialRef() void {
25 comptime {
26 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
27 var target: [*]u8 = @ptrCast([*]u8, &buf);
28 const slice = target[0..15 :0];
29 _ = slice;
30 }
31}
32export fn foo_cvector_ConstPtrSpecialBaseArray() void {
33 comptime {
34 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
35 var target: [*c]u8 = &buf;
36 const slice = target[0..15 :0];
37 _ = slice;
38 }
39}
40export fn foo_cvector_ConstPtrSpecialRef() void {
41 comptime {
42 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
43 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
44 const slice = target[0..15 :0];
45 _ = slice;
46 }
47}
48export fn foo_slice() void {
49 comptime {
50 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
51 var target: []u8 = &buf;
52 const slice = target[0..15 :0];
53 _ = slice;
54 }
55}
56
57// error
58// backend=stage2
59// target=native
60//
61// :4:33: error: slice end index 15 exceeds bounds of containing decl of type '[14:0]u8'
62// :12:33: error: slice end index 15 exceeds bounds of containing decl of type '[14:0]u8'
63// :20:33: error: slice end index 15 exceeds bounds of containing decl of type '[14:0]u8'
64// :28:33: error: slice end index 15 exceeds bounds of containing decl of type '[14:0]u8'
65// :36:33: error: slice end index 15 exceeds bounds of containing decl of type '[14:0]u8'
66// :44:33: error: slice end index 15 exceeds bounds of containing decl of type '[14:0]u8'
67// :52:33: error: end index 15 out of bounds for slice of length 14
test/cases/compile_errors/comptime_slice-sentinel_is_out_of_bounds_unterminated.zig created+67
...@@ -0,0 +1,67 @@
1export fn foo_array() void {
2 comptime {
3 var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
4 const slice = target[0..14 :0];
5 _ = slice;
6 }
7}
8export fn foo_ptr_array() void {
9 comptime {
10 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
11 var target = &buf;
12 const slice = target[0..14 :0];
13 _ = slice;
14 }
15}
16export fn foo_vector_ConstPtrSpecialBaseArray() void {
17 comptime {
18 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
19 var target: [*]u8 = &buf;
20 const slice = target[0..14 :0];
21 _ = slice;
22 }
23}
24export fn foo_vector_ConstPtrSpecialRef() void {
25 comptime {
26 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
27 var target: [*]u8 = @ptrCast([*]u8, &buf);
28 const slice = target[0..14 :0];
29 _ = slice;
30 }
31}
32export fn foo_cvector_ConstPtrSpecialBaseArray() void {
33 comptime {
34 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
35 var target: [*c]u8 = &buf;
36 const slice = target[0..14 :0];
37 _ = slice;
38 }
39}
40export fn foo_cvector_ConstPtrSpecialRef() void {
41 comptime {
42 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
43 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
44 const slice = target[0..14 :0];
45 _ = slice;
46 }
47}
48export fn foo_slice() void {
49 comptime {
50 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
51 var target: []u8 = &buf;
52 const slice = target[0..14 :0];
53 _ = slice;
54 }
55}
56
57// error
58// backend=stage2
59// target=native
60//
61// :4:33: error: slice end index 14 exceeds bounds of containing decl of type '[14]u8'
62// :12:33: error: slice end index 14 exceeds bounds of containing decl of type '[14]u8'
63// :20:33: error: slice end index 14 exceeds bounds of containing decl of type '[14]u8'
64// :28:33: error: slice end index 14 exceeds bounds of containing decl of type '[14]u8'
65// :36:33: error: slice end index 14 exceeds bounds of containing decl of type '[14]u8'
66// :44:33: error: slice end index 14 exceeds bounds of containing decl of type '[14]u8'
67// :52:33: error: slice end index 14 exceeds bounds of containing decl of type '[14]u8'
test/cases/compile_errors/comptime_slice_of_an_undefined_slice.zig created+11
...@@ -0,0 +1,11 @@
1comptime {
2 var a: []u8 = undefined;
3 var b = a[0..10];
4 _ = b;
5}
6
7// error
8// backend=stage2
9// target=native
10//
11// :3:14: error: slice of undefined
test/cases/compile_errors/stage1/obj/comptime_slice-sentinel_does_not_match_memory_at_target_index_terminated.zig deleted-67
...@@ -1,67 +0,0 @@
1export fn foo_array() void {
2 comptime {
3 var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
4 const slice = target[0..3 :0];
5 _ = slice;
6 }
7}
8export fn foo_ptr_array() void {
9 comptime {
10 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
11 var target = &buf;
12 const slice = target[0..3 :0];
13 _ = slice;
14 }
15}
16export fn foo_vector_ConstPtrSpecialBaseArray() void {
17 comptime {
18 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
19 var target: [*]u8 = &buf;
20 const slice = target[0..3 :0];
21 _ = slice;
22 }
23}
24export fn foo_vector_ConstPtrSpecialRef() void {
25 comptime {
26 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
27 var target: [*]u8 = @ptrCast([*]u8, &buf);
28 const slice = target[0..3 :0];
29 _ = slice;
30 }
31}
32export fn foo_cvector_ConstPtrSpecialBaseArray() void {
33 comptime {
34 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
35 var target: [*c]u8 = &buf;
36 const slice = target[0..3 :0];
37 _ = slice;
38 }
39}
40export fn foo_cvector_ConstPtrSpecialRef() void {
41 comptime {
42 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
43 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
44 const slice = target[0..3 :0];
45 _ = slice;
46 }
47}
48export fn foo_slice() void {
49 comptime {
50 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
51 var target: []u8 = &buf;
52 const slice = target[0..3 :0];
53 _ = slice;
54 }
55}
56
57// error
58// backend=stage1
59// target=native
60//
61// :4:29: error: slice-sentinel does not match memory at target index
62// :12:29: error: slice-sentinel does not match memory at target index
63// :20:29: error: slice-sentinel does not match memory at target index
64// :28:29: error: slice-sentinel does not match memory at target index
65// :36:29: error: slice-sentinel does not match memory at target index
66// :44:29: error: slice-sentinel does not match memory at target index
67// :52:29: error: slice-sentinel does not match memory at target index
test/cases/compile_errors/stage1/obj/comptime_slice-sentinel_does_not_match_memory_at_target_index_unterminated.zig deleted-67
...@@ -1,67 +0,0 @@
1export fn foo_array() void {
2 comptime {
3 var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
4 const slice = target[0..3 :0];
5 _ = slice;
6 }
7}
8export fn foo_ptr_array() void {
9 comptime {
10 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
11 var target = &buf;
12 const slice = target[0..3 :0];
13 _ = slice;
14 }
15}
16export fn foo_vector_ConstPtrSpecialBaseArray() void {
17 comptime {
18 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
19 var target: [*]u8 = &buf;
20 const slice = target[0..3 :0];
21 _ = slice;
22 }
23}
24export fn foo_vector_ConstPtrSpecialRef() void {
25 comptime {
26 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
27 var target: [*]u8 = @ptrCast([*]u8, &buf);
28 const slice = target[0..3 :0];
29 _ = slice;
30 }
31}
32export fn foo_cvector_ConstPtrSpecialBaseArray() void {
33 comptime {
34 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
35 var target: [*c]u8 = &buf;
36 const slice = target[0..3 :0];
37 _ = slice;
38 }
39}
40export fn foo_cvector_ConstPtrSpecialRef() void {
41 comptime {
42 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
43 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
44 const slice = target[0..3 :0];
45 _ = slice;
46 }
47}
48export fn foo_slice() void {
49 comptime {
50 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
51 var target: []u8 = &buf;
52 const slice = target[0..3 :0];
53 _ = slice;
54 }
55}
56
57// error
58// backend=stage1
59// target=native
60//
61// :4:29: error: slice-sentinel does not match memory at target index
62// :12:29: error: slice-sentinel does not match memory at target index
63// :20:29: error: slice-sentinel does not match memory at target index
64// :28:29: error: slice-sentinel does not match memory at target index
65// :36:29: error: slice-sentinel does not match memory at target index
66// :44:29: error: slice-sentinel does not match memory at target index
67// :52:29: error: slice-sentinel does not match memory at target index
test/cases/compile_errors/stage1/obj/comptime_slice-sentinel_does_not_match_target-sentinel.zig deleted-67
...@@ -1,67 +0,0 @@
1export fn foo_array() void {
2 comptime {
3 var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
4 const slice = target[0..14 :255];
5 _ = slice;
6 }
7}
8export fn foo_ptr_array() void {
9 comptime {
10 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
11 var target = &buf;
12 const slice = target[0..14 :255];
13 _ = slice;
14 }
15}
16export fn foo_vector_ConstPtrSpecialBaseArray() void {
17 comptime {
18 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
19 var target: [*]u8 = &buf;
20 const slice = target[0..14 :255];
21 _ = slice;
22 }
23}
24export fn foo_vector_ConstPtrSpecialRef() void {
25 comptime {
26 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
27 var target: [*]u8 = @ptrCast([*]u8, &buf);
28 const slice = target[0..14 :255];
29 _ = slice;
30 }
31}
32export fn foo_cvector_ConstPtrSpecialBaseArray() void {
33 comptime {
34 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
35 var target: [*c]u8 = &buf;
36 const slice = target[0..14 :255];
37 _ = slice;
38 }
39}
40export fn foo_cvector_ConstPtrSpecialRef() void {
41 comptime {
42 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
43 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
44 const slice = target[0..14 :255];
45 _ = slice;
46 }
47}
48export fn foo_slice() void {
49 comptime {
50 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
51 var target: []u8 = &buf;
52 const slice = target[0..14 :255];
53 _ = slice;
54 }
55}
56
57// error
58// backend=stage1
59// target=native
60//
61// :4:29: error: slice-sentinel does not match target-sentinel
62// :12:29: error: slice-sentinel does not match target-sentinel
63// :20:29: error: slice-sentinel does not match target-sentinel
64// :28:29: error: slice-sentinel does not match target-sentinel
65// :36:29: error: slice-sentinel does not match target-sentinel
66// :44:29: error: slice-sentinel does not match target-sentinel
67// :52:29: error: slice-sentinel does not match target-sentinel
test/cases/compile_errors/stage1/obj/comptime_slice-sentinel_is_out_of_bounds_terminated.zig deleted-67
...@@ -1,67 +0,0 @@
1export fn foo_array() void {
2 comptime {
3 var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
4 const slice = target[0..15 :1];
5 _ = slice;
6 }
7}
8export fn foo_ptr_array() void {
9 comptime {
10 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
11 var target = &buf;
12 const slice = target[0..15 :0];
13 _ = slice;
14 }
15}
16export fn foo_vector_ConstPtrSpecialBaseArray() void {
17 comptime {
18 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
19 var target: [*]u8 = &buf;
20 const slice = target[0..15 :0];
21 _ = slice;
22 }
23}
24export fn foo_vector_ConstPtrSpecialRef() void {
25 comptime {
26 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
27 var target: [*]u8 = @ptrCast([*]u8, &buf);
28 const slice = target[0..15 :0];
29 _ = slice;
30 }
31}
32export fn foo_cvector_ConstPtrSpecialBaseArray() void {
33 comptime {
34 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
35 var target: [*c]u8 = &buf;
36 const slice = target[0..15 :0];
37 _ = slice;
38 }
39}
40export fn foo_cvector_ConstPtrSpecialRef() void {
41 comptime {
42 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
43 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
44 const slice = target[0..15 :0];
45 _ = slice;
46 }
47}
48export fn foo_slice() void {
49 comptime {
50 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
51 var target: []u8 = &buf;
52 const slice = target[0..15 :0];
53 _ = slice;
54 }
55}
56
57// error
58// backend=stage1
59// target=native
60//
61// :4:29: error: out of bounds slice
62// :12:29: error: out of bounds slice
63// :20:29: error: out of bounds slice
64// :28:29: error: out of bounds slice
65// :36:29: error: out of bounds slice
66// :44:29: error: out of bounds slice
67// :52:29: error: out of bounds slice
test/cases/compile_errors/stage1/obj/comptime_slice-sentinel_is_out_of_bounds_unterminated.zig deleted-67
...@@ -1,67 +0,0 @@
1export fn foo_array() void {
2 comptime {
3 var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
4 const slice = target[0..14 :0];
5 _ = slice;
6 }
7}
8export fn foo_ptr_array() void {
9 comptime {
10 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
11 var target = &buf;
12 const slice = target[0..14 :0];
13 _ = slice;
14 }
15}
16export fn foo_vector_ConstPtrSpecialBaseArray() void {
17 comptime {
18 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
19 var target: [*]u8 = &buf;
20 const slice = target[0..14 :0];
21 _ = slice;
22 }
23}
24export fn foo_vector_ConstPtrSpecialRef() void {
25 comptime {
26 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
27 var target: [*]u8 = @ptrCast([*]u8, &buf);
28 const slice = target[0..14 :0];
29 _ = slice;
30 }
31}
32export fn foo_cvector_ConstPtrSpecialBaseArray() void {
33 comptime {
34 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
35 var target: [*c]u8 = &buf;
36 const slice = target[0..14 :0];
37 _ = slice;
38 }
39}
40export fn foo_cvector_ConstPtrSpecialRef() void {
41 comptime {
42 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
43 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
44 const slice = target[0..14 :0];
45 _ = slice;
46 }
47}
48export fn foo_slice() void {
49 comptime {
50 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
51 var target: []u8 = &buf;
52 const slice = target[0..14 :0];
53 _ = slice;
54 }
55}
56
57// error
58// backend=stage1
59// target=native
60//
61// :4:29: error: slice-sentinel is out of bounds
62// :12:29: error: slice-sentinel is out of bounds
63// :20:29: error: slice-sentinel is out of bounds
64// :28:29: error: slice-sentinel is out of bounds
65// :36:29: error: slice-sentinel is out of bounds
66// :44:29: error: slice-sentinel is out of bounds
67// :52:29: error: slice-sentinel is out of bounds
test/cases/compile_errors/stage1/obj/comptime_slice_of_an_undefined_slice.zig deleted-11
...@@ -1,11 +0,0 @@
1comptime {
2 var a: []u8 = undefined;
3 var b = a[0..10];
4 _ = b;
5}
6
7// error
8// backend=stage1
9// target=native
10//
11// tmp.zig:3:14: error: slice of undefined