commit 02dc0732604236a57b43b9612d9b0571f06f905a (tree) parent d26d696ee01d3a17d17cde24c8841e7f551ba5f2 Author: Veikka Tuominen <git@vexu.eu> Date: Thu, 28 Jul 2022 22:21:49 +0300 Sema: check comptime slice sentinel Diffstat:
13 files changed, 450 insertions(+), 359 deletions(-)
diff --git a/src/Sema.zig b/src/Sema.zig @@ -25150,7 +25150,10 @@ fn analyzeSlice( if (!end_is_len) { const end = try sema.coerce(block, Type.usize, uncasted_end_opt, end_src); if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| { - if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| { + if (try sema.resolveMaybeUndefVal(block, src, ptr_or_slice)) |slice_val| { + if (slice_val.isUndef()) { + return sema.fail(block, src, "slice of undefined", .{}); + } const has_sentinel = slice_ty.sentinel() != null; var int_payload: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, @@ -25213,8 +25216,8 @@ fn analyzeSlice( }; // requirement: start <= end - if (try sema.resolveDefinedValue(block, src, end)) |end_val| { - if (try sema.resolveDefinedValue(block, src, start)) |start_val| { + if (try sema.resolveDefinedValue(block, end_src, end)) |end_val| { + if (try sema.resolveDefinedValue(block, start_src, start)) |start_val| { if (try sema.compare(block, src, start_val, .gt, end_val, Type.usize)) { return sema.fail( block, @@ -25226,6 +25229,45 @@ fn analyzeSlice( }, ); } + if (try sema.resolveMaybeUndefVal(block, ptr_src, new_ptr)) |ptr_val| sentinel_check: { + const expected_sentinel = sentinel orelse break :sentinel_check; + const start_int = start_val.getUnsignedInt(sema.mod.getTarget()).?; + const end_int = end_val.getUnsignedInt(sema.mod.getTarget()).?; + const sentinel_index = try sema.usizeCast(block, end_src, end_int - start_int); + + const elem_ptr = try ptr_val.elemPtr(sema.typeOf(new_ptr), sema.arena, sentinel_index, sema.mod); + const res = try sema.pointerDerefExtra(block, src, elem_ptr, elem_ty, false); + const actual_sentinel = switch (res) { + .runtime_load => break :sentinel_check, + .val => |v| v, + .needed_well_defined => |ty| return sema.fail( + block, + src, + "comptime dereference requires '{}' to have a well-defined layout, but it does not.", + .{ty.fmt(sema.mod)}, + ), + .out_of_bounds => |ty| return sema.fail( + block, + end_src, + "slice end index {d} exceeds bounds of containing decl of type '{}'", + .{ end_int, ty.fmt(sema.mod) }, + ), + }; + + if (!actual_sentinel.eql(expected_sentinel, elem_ty, sema.mod)) { + const msg = msg: { + const msg = try sema.errMsg(block, src, "value in memory does not match slice sentinel", .{}); + errdefer msg.destroy(sema.gpa); + try sema.errNote(block, src, msg, "expected '{}', found '{}'", .{ + expected_sentinel.fmtValue(elem_ty, sema.mod), + actual_sentinel.fmtValue(elem_ty, sema.mod), + }); + + break :msg msg; + }; + return sema.failWithOwnedErrorMsg(block, msg); + } + } } } @@ -27866,9 +27908,36 @@ pub fn analyzeAddrspace( /// Returns `null` if the pointer contents cannot be loaded at comptime. fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr_ty: Type) CompileError!?Value { const load_ty = ptr_ty.childType(); + const res = try sema.pointerDerefExtra(block, src, ptr_val, load_ty, true); + switch (res) { + .runtime_load => return null, + .val => |v| return v, + .needed_well_defined => |ty| return sema.fail( + block, + src, + "comptime dereference requires '{}' to have a well-defined layout, but it does not.", + .{ty.fmt(sema.mod)}, + ), + .out_of_bounds => |ty| return sema.fail( + block, + src, + "dereference of '{}' exceeds bounds of containing decl of type '{}'", + .{ ptr_ty.fmt(sema.mod), ty.fmt(sema.mod) }, + ), + } +} + +const DerefResult = union(enum) { + runtime_load, + val: Value, + needed_well_defined: Type, + out_of_bounds: Type, +}; + +fn pointerDerefExtra(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, load_ty: Type, want_mutable: bool) CompileError!DerefResult { const target = sema.mod.getTarget(); const deref = sema.beginComptimePtrLoad(block, src, ptr_val, load_ty) catch |err| switch (err) { - error.RuntimeLoad => return null, + error.RuntimeLoad => return DerefResult{ .runtime_load = {} }, else => |e| return e, }; @@ -27879,39 +27948,40 @@ fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr if (coerce_in_mem_ok) { // We have a Value that lines up in virtual memory exactly with what we want to load, // and it is in-memory coercible to load_ty. It may be returned without modifications. - if (deref.is_mutable) { + if (deref.is_mutable and want_mutable) { // The decl whose value we are obtaining here may be overwritten with // a different value upon further semantic analysis, which would // invalidate this memory. So we must copy here. - return try tv.val.copy(sema.arena); + return DerefResult{ .val = try tv.val.copy(sema.arena) }; } - return tv.val; + return DerefResult{ .val = tv.val }; } } // The type is not in-memory coercible or the direct dereference failed, so it must // be bitcast according to the pointer type we are performing the load through. - if (!load_ty.hasWellDefinedLayout()) - return sema.fail(block, src, "comptime dereference requires '{}' to have a well-defined layout, but it does not.", .{load_ty.fmt(sema.mod)}); + if (!load_ty.hasWellDefinedLayout()) { + return DerefResult{ .needed_well_defined = load_ty }; + } const load_sz = try sema.typeAbiSize(block, src, load_ty); // Try the smaller bit-cast first, since that's more efficient than using the larger `parent` if (deref.pointee) |tv| if (load_sz <= try sema.typeAbiSize(block, src, tv.ty)) - return try sema.bitCastVal(block, src, tv.val, tv.ty, load_ty, 0); + return DerefResult{ .val = try sema.bitCastVal(block, src, tv.val, tv.ty, load_ty, 0) }; // If that fails, try to bit-cast from the largest parent value with a well-defined layout if (deref.parent) |parent| if (load_sz + parent.byte_offset <= try sema.typeAbiSize(block, src, parent.tv.ty)) - return try sema.bitCastVal(block, src, parent.tv.val, parent.tv.ty, load_ty, parent.byte_offset); + return DerefResult{ .val = try sema.bitCastVal(block, src, parent.tv.val, parent.tv.ty, load_ty, parent.byte_offset) }; if (deref.ty_without_well_defined_layout) |bad_ty| { // We got no parent for bit-casting, or the parent we got was too small. Either way, the problem // is that some type we encountered when de-referencing does not have a well-defined layout. - return sema.fail(block, src, "comptime dereference requires '{}' to have a well-defined layout, but it does not.", .{bad_ty.fmt(sema.mod)}); + return DerefResult{ .needed_well_defined = bad_ty }; } else { // If all encountered types had well-defined layouts, the parent is the root decl and it just // wasn't big enough for the load. - 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) }); + return DerefResult{ .out_of_bounds = deref.parent.?.tv.ty }; } } diff --git a/test/cases/compile_errors/comptime_slice-sentinel_does_not_match_memory_at_target_index_terminated.zig b/test/cases/compile_errors/comptime_slice-sentinel_does_not_match_memory_at_target_index_terminated.zig @@ -0,0 +1,74 @@ +export fn foo_array() void { + comptime { + var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + const slice = target[0..3 :0]; + _ = slice; + } +} +export fn foo_ptr_array() void { + comptime { + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target = &buf; + const slice = target[0..3 :0]; + _ = slice; + } +} +export fn foo_vector_ConstPtrSpecialBaseArray() void { + comptime { + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: [*]u8 = &buf; + const slice = target[0..3 :0]; + _ = slice; + } +} +export fn foo_vector_ConstPtrSpecialRef() void { + comptime { + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: [*]u8 = @ptrCast([*]u8, &buf); + const slice = target[0..3 :0]; + _ = slice; + } +} +export fn foo_cvector_ConstPtrSpecialBaseArray() void { + comptime { + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: [*c]u8 = &buf; + const slice = target[0..3 :0]; + _ = slice; + } +} +export fn foo_cvector_ConstPtrSpecialRef() void { + comptime { + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: [*c]u8 = @ptrCast([*c]u8, &buf); + const slice = target[0..3 :0]; + _ = slice; + } +} +export fn foo_slice() void { + comptime { + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: []u8 = &buf; + const slice = target[0..3 :0]; + _ = slice; + } +} + +// error +// 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' diff --git a/test/cases/compile_errors/comptime_slice-sentinel_does_not_match_memory_at_target_index_unterminated.zig b/test/cases/compile_errors/comptime_slice-sentinel_does_not_match_memory_at_target_index_unterminated.zig @@ -0,0 +1,74 @@ +export fn foo_array() void { + comptime { + var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + const slice = target[0..3 :0]; + _ = slice; + } +} +export fn foo_ptr_array() void { + comptime { + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target = &buf; + const slice = target[0..3 :0]; + _ = slice; + } +} +export fn foo_vector_ConstPtrSpecialBaseArray() void { + comptime { + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: [*]u8 = &buf; + const slice = target[0..3 :0]; + _ = slice; + } +} +export fn foo_vector_ConstPtrSpecialRef() void { + comptime { + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: [*]u8 = @ptrCast([*]u8, &buf); + const slice = target[0..3 :0]; + _ = slice; + } +} +export fn foo_cvector_ConstPtrSpecialBaseArray() void { + comptime { + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: [*c]u8 = &buf; + const slice = target[0..3 :0]; + _ = slice; + } +} +export fn foo_cvector_ConstPtrSpecialRef() void { + comptime { + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: [*c]u8 = @ptrCast([*c]u8, &buf); + const slice = target[0..3 :0]; + _ = slice; + } +} +export fn foo_slice() void { + comptime { + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: []u8 = &buf; + const slice = target[0..3 :0]; + _ = slice; + } +} + +// error +// 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' diff --git a/test/cases/compile_errors/comptime_slice-sentinel_does_not_match_target-sentinel.zig b/test/cases/compile_errors/comptime_slice-sentinel_does_not_match_target-sentinel.zig @@ -0,0 +1,74 @@ +export fn foo_array() void { + comptime { + var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + const slice = target[0..14 :255]; + _ = slice; + } +} +export fn foo_ptr_array() void { + comptime { + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target = &buf; + const slice = target[0..14 :255]; + _ = slice; + } +} +export fn foo_vector_ConstPtrSpecialBaseArray() void { + comptime { + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: [*]u8 = &buf; + const slice = target[0..14 :255]; + _ = slice; + } +} +export fn foo_vector_ConstPtrSpecialRef() void { + comptime { + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: [*]u8 = @ptrCast([*]u8, &buf); + const slice = target[0..14 :255]; + _ = slice; + } +} +export fn foo_cvector_ConstPtrSpecialBaseArray() void { + comptime { + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: [*c]u8 = &buf; + const slice = target[0..14 :255]; + _ = slice; + } +} +export fn foo_cvector_ConstPtrSpecialRef() void { + comptime { + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: [*c]u8 = @ptrCast([*c]u8, &buf); + const slice = target[0..14 :255]; + _ = slice; + } +} +export fn foo_slice() void { + comptime { + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: []u8 = &buf; + const slice = target[0..14 :255]; + _ = slice; + } +} + +// error +// 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' diff --git a/test/cases/compile_errors/comptime_slice-sentinel_is_out_of_bounds_terminated.zig b/test/cases/compile_errors/comptime_slice-sentinel_is_out_of_bounds_terminated.zig @@ -0,0 +1,67 @@ +export fn foo_array() void { + comptime { + var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + const slice = target[0..15 :1]; + _ = slice; + } +} +export fn foo_ptr_array() void { + comptime { + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target = &buf; + const slice = target[0..15 :0]; + _ = slice; + } +} +export fn foo_vector_ConstPtrSpecialBaseArray() void { + comptime { + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: [*]u8 = &buf; + const slice = target[0..15 :0]; + _ = slice; + } +} +export fn foo_vector_ConstPtrSpecialRef() void { + comptime { + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: [*]u8 = @ptrCast([*]u8, &buf); + const slice = target[0..15 :0]; + _ = slice; + } +} +export fn foo_cvector_ConstPtrSpecialBaseArray() void { + comptime { + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: [*c]u8 = &buf; + const slice = target[0..15 :0]; + _ = slice; + } +} +export fn foo_cvector_ConstPtrSpecialRef() void { + comptime { + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: [*c]u8 = @ptrCast([*c]u8, &buf); + const slice = target[0..15 :0]; + _ = slice; + } +} +export fn foo_slice() void { + comptime { + var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: []u8 = &buf; + const slice = target[0..15 :0]; + _ = slice; + } +} + +// error +// 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 diff --git a/test/cases/compile_errors/comptime_slice-sentinel_is_out_of_bounds_unterminated.zig b/test/cases/compile_errors/comptime_slice-sentinel_is_out_of_bounds_unterminated.zig @@ -0,0 +1,67 @@ +export fn foo_array() void { + comptime { + var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + const slice = target[0..14 :0]; + _ = slice; + } +} +export fn foo_ptr_array() void { + comptime { + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target = &buf; + const slice = target[0..14 :0]; + _ = slice; + } +} +export fn foo_vector_ConstPtrSpecialBaseArray() void { + comptime { + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: [*]u8 = &buf; + const slice = target[0..14 :0]; + _ = slice; + } +} +export fn foo_vector_ConstPtrSpecialRef() void { + comptime { + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: [*]u8 = @ptrCast([*]u8, &buf); + const slice = target[0..14 :0]; + _ = slice; + } +} +export fn foo_cvector_ConstPtrSpecialBaseArray() void { + comptime { + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: [*c]u8 = &buf; + const slice = target[0..14 :0]; + _ = slice; + } +} +export fn foo_cvector_ConstPtrSpecialRef() void { + comptime { + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: [*c]u8 = @ptrCast([*c]u8, &buf); + const slice = target[0..14 :0]; + _ = slice; + } +} +export fn foo_slice() void { + comptime { + var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; + var target: []u8 = &buf; + const slice = target[0..14 :0]; + _ = slice; + } +} + +// error +// 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' diff --git a/test/cases/compile_errors/comptime_slice_of_an_undefined_slice.zig b/test/cases/compile_errors/comptime_slice_of_an_undefined_slice.zig @@ -0,0 +1,11 @@ +comptime { + var a: []u8 = undefined; + var b = a[0..10]; + _ = b; +} + +// error +// backend=stage2 +// target=native +// +// :3:14: error: slice of undefined diff --git a/test/cases/compile_errors/stage1/obj/comptime_slice-sentinel_does_not_match_memory_at_target_index_terminated.zig b/test/cases/compile_errors/stage1/obj/comptime_slice-sentinel_does_not_match_memory_at_target_index_terminated.zig @@ -1,67 +0,0 @@ -export fn foo_array() void { - comptime { - var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - const slice = target[0..3 :0]; - _ = slice; - } -} -export fn foo_ptr_array() void { - comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target = &buf; - const slice = target[0..3 :0]; - _ = slice; - } -} -export fn foo_vector_ConstPtrSpecialBaseArray() void { - comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: [*]u8 = &buf; - const slice = target[0..3 :0]; - _ = slice; - } -} -export fn foo_vector_ConstPtrSpecialRef() void { - comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: [*]u8 = @ptrCast([*]u8, &buf); - const slice = target[0..3 :0]; - _ = slice; - } -} -export fn foo_cvector_ConstPtrSpecialBaseArray() void { - comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: [*c]u8 = &buf; - const slice = target[0..3 :0]; - _ = slice; - } -} -export fn foo_cvector_ConstPtrSpecialRef() void { - comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: [*c]u8 = @ptrCast([*c]u8, &buf); - const slice = target[0..3 :0]; - _ = slice; - } -} -export fn foo_slice() void { - comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: []u8 = &buf; - const slice = target[0..3 :0]; - _ = slice; - } -} - -// error -// backend=stage1 -// target=native -// -// :4:29: error: slice-sentinel does not match memory at target index -// :12:29: error: slice-sentinel does not match memory at target index -// :20:29: error: slice-sentinel does not match memory at target index -// :28:29: error: slice-sentinel does not match memory at target index -// :36:29: error: slice-sentinel does not match memory at target index -// :44:29: error: slice-sentinel does not match memory at target index -// :52:29: error: slice-sentinel does not match memory at target index diff --git a/test/cases/compile_errors/stage1/obj/comptime_slice-sentinel_does_not_match_memory_at_target_index_unterminated.zig b/test/cases/compile_errors/stage1/obj/comptime_slice-sentinel_does_not_match_memory_at_target_index_unterminated.zig @@ -1,67 +0,0 @@ -export fn foo_array() void { - comptime { - var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - const slice = target[0..3 :0]; - _ = slice; - } -} -export fn foo_ptr_array() void { - comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target = &buf; - const slice = target[0..3 :0]; - _ = slice; - } -} -export fn foo_vector_ConstPtrSpecialBaseArray() void { - comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: [*]u8 = &buf; - const slice = target[0..3 :0]; - _ = slice; - } -} -export fn foo_vector_ConstPtrSpecialRef() void { - comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: [*]u8 = @ptrCast([*]u8, &buf); - const slice = target[0..3 :0]; - _ = slice; - } -} -export fn foo_cvector_ConstPtrSpecialBaseArray() void { - comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: [*c]u8 = &buf; - const slice = target[0..3 :0]; - _ = slice; - } -} -export fn foo_cvector_ConstPtrSpecialRef() void { - comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: [*c]u8 = @ptrCast([*c]u8, &buf); - const slice = target[0..3 :0]; - _ = slice; - } -} -export fn foo_slice() void { - comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: []u8 = &buf; - const slice = target[0..3 :0]; - _ = slice; - } -} - -// error -// backend=stage1 -// target=native -// -// :4:29: error: slice-sentinel does not match memory at target index -// :12:29: error: slice-sentinel does not match memory at target index -// :20:29: error: slice-sentinel does not match memory at target index -// :28:29: error: slice-sentinel does not match memory at target index -// :36:29: error: slice-sentinel does not match memory at target index -// :44:29: error: slice-sentinel does not match memory at target index -// :52:29: error: slice-sentinel does not match memory at target index diff --git a/test/cases/compile_errors/stage1/obj/comptime_slice-sentinel_does_not_match_target-sentinel.zig b/test/cases/compile_errors/stage1/obj/comptime_slice-sentinel_does_not_match_target-sentinel.zig @@ -1,67 +0,0 @@ -export fn foo_array() void { - comptime { - var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - const slice = target[0..14 :255]; - _ = slice; - } -} -export fn foo_ptr_array() void { - comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target = &buf; - const slice = target[0..14 :255]; - _ = slice; - } -} -export fn foo_vector_ConstPtrSpecialBaseArray() void { - comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: [*]u8 = &buf; - const slice = target[0..14 :255]; - _ = slice; - } -} -export fn foo_vector_ConstPtrSpecialRef() void { - comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: [*]u8 = @ptrCast([*]u8, &buf); - const slice = target[0..14 :255]; - _ = slice; - } -} -export fn foo_cvector_ConstPtrSpecialBaseArray() void { - comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: [*c]u8 = &buf; - const slice = target[0..14 :255]; - _ = slice; - } -} -export fn foo_cvector_ConstPtrSpecialRef() void { - comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: [*c]u8 = @ptrCast([*c]u8, &buf); - const slice = target[0..14 :255]; - _ = slice; - } -} -export fn foo_slice() void { - comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: []u8 = &buf; - const slice = target[0..14 :255]; - _ = slice; - } -} - -// error -// backend=stage1 -// target=native -// -// :4:29: error: slice-sentinel does not match target-sentinel -// :12:29: error: slice-sentinel does not match target-sentinel -// :20:29: error: slice-sentinel does not match target-sentinel -// :28:29: error: slice-sentinel does not match target-sentinel -// :36:29: error: slice-sentinel does not match target-sentinel -// :44:29: error: slice-sentinel does not match target-sentinel -// :52:29: error: slice-sentinel does not match target-sentinel diff --git a/test/cases/compile_errors/stage1/obj/comptime_slice-sentinel_is_out_of_bounds_terminated.zig b/test/cases/compile_errors/stage1/obj/comptime_slice-sentinel_is_out_of_bounds_terminated.zig @@ -1,67 +0,0 @@ -export fn foo_array() void { - comptime { - var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - const slice = target[0..15 :1]; - _ = slice; - } -} -export fn foo_ptr_array() void { - comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target = &buf; - const slice = target[0..15 :0]; - _ = slice; - } -} -export fn foo_vector_ConstPtrSpecialBaseArray() void { - comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: [*]u8 = &buf; - const slice = target[0..15 :0]; - _ = slice; - } -} -export fn foo_vector_ConstPtrSpecialRef() void { - comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: [*]u8 = @ptrCast([*]u8, &buf); - const slice = target[0..15 :0]; - _ = slice; - } -} -export fn foo_cvector_ConstPtrSpecialBaseArray() void { - comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: [*c]u8 = &buf; - const slice = target[0..15 :0]; - _ = slice; - } -} -export fn foo_cvector_ConstPtrSpecialRef() void { - comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: [*c]u8 = @ptrCast([*c]u8, &buf); - const slice = target[0..15 :0]; - _ = slice; - } -} -export fn foo_slice() void { - comptime { - var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: []u8 = &buf; - const slice = target[0..15 :0]; - _ = slice; - } -} - -// error -// backend=stage1 -// target=native -// -// :4:29: error: out of bounds slice -// :12:29: error: out of bounds slice -// :20:29: error: out of bounds slice -// :28:29: error: out of bounds slice -// :36:29: error: out of bounds slice -// :44:29: error: out of bounds slice -// :52:29: error: out of bounds slice diff --git a/test/cases/compile_errors/stage1/obj/comptime_slice-sentinel_is_out_of_bounds_unterminated.zig b/test/cases/compile_errors/stage1/obj/comptime_slice-sentinel_is_out_of_bounds_unterminated.zig @@ -1,67 +0,0 @@ -export fn foo_array() void { - comptime { - var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - const slice = target[0..14 :0]; - _ = slice; - } -} -export fn foo_ptr_array() void { - comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target = &buf; - const slice = target[0..14 :0]; - _ = slice; - } -} -export fn foo_vector_ConstPtrSpecialBaseArray() void { - comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: [*]u8 = &buf; - const slice = target[0..14 :0]; - _ = slice; - } -} -export fn foo_vector_ConstPtrSpecialRef() void { - comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: [*]u8 = @ptrCast([*]u8, &buf); - const slice = target[0..14 :0]; - _ = slice; - } -} -export fn foo_cvector_ConstPtrSpecialBaseArray() void { - comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: [*c]u8 = &buf; - const slice = target[0..14 :0]; - _ = slice; - } -} -export fn foo_cvector_ConstPtrSpecialRef() void { - comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: [*c]u8 = @ptrCast([*c]u8, &buf); - const slice = target[0..14 :0]; - _ = slice; - } -} -export fn foo_slice() void { - comptime { - var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10; - var target: []u8 = &buf; - const slice = target[0..14 :0]; - _ = slice; - } -} - -// error -// backend=stage1 -// target=native -// -// :4:29: error: slice-sentinel is out of bounds -// :12:29: error: slice-sentinel is out of bounds -// :20:29: error: slice-sentinel is out of bounds -// :28:29: error: slice-sentinel is out of bounds -// :36:29: error: slice-sentinel is out of bounds -// :44:29: error: slice-sentinel is out of bounds -// :52:29: error: slice-sentinel is out of bounds diff --git a/test/cases/compile_errors/stage1/obj/comptime_slice_of_an_undefined_slice.zig b/test/cases/compile_errors/stage1/obj/comptime_slice_of_an_undefined_slice.zig @@ -1,11 +0,0 @@ -comptime { - var a: []u8 = undefined; - var b = a[0..10]; - _ = b; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:3:14: error: slice of undefined