Commit db4c06ce60
Changed files (4)
src
test
stage1
src/ir.cpp
@@ -26583,7 +26583,6 @@ done_with_return_type:
if (parent_ptr == nullptr)
return ira->codegen->invalid_inst_gen;
-
if (parent_ptr->special == ConstValSpecialUndef) {
array_val = nullptr;
abs_offset = 0;
@@ -26746,6 +26745,113 @@ done_with_return_type:
return ira->codegen->invalid_inst_gen;
}
+ // check sentinel when target is comptime-known
+ {
+ if (!sentinel_val)
+ goto exit_check_sentinel;
+
+ switch (ptr_ptr->value->data.x_ptr.mut) {
+ case ConstPtrMutComptimeConst:
+ case ConstPtrMutComptimeVar:
+ break;
+ case ConstPtrMutRuntimeVar:
+ case ConstPtrMutInfer:
+ goto exit_check_sentinel;
+ }
+
+ // prepare check parameters
+ ZigValue *target = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.base.source_node);
+ if (target == nullptr)
+ return ira->codegen->invalid_inst_gen;
+
+ uint64_t target_len = 0;
+ ZigValue *target_sentinel = nullptr;
+ ZigValue *target_elements = nullptr;
+
+ for (;;) {
+ if (target->type->id == ZigTypeIdArray) {
+ // handle `[N]T`
+ target_len = target->type->data.array.len;
+ target_sentinel = target->type->data.array.sentinel;
+ target_elements = target->data.x_array.data.s_none.elements;
+ break;
+ } else if (target->type->id == ZigTypeIdPointer && target->type->data.pointer.child_type->id == ZigTypeIdArray) {
+ // handle `*[N]T`
+ target = const_ptr_pointee(ira, ira->codegen, target, instruction->base.base.source_node);
+ if (target == nullptr)
+ return ira->codegen->invalid_inst_gen;
+ assert(target->type->id == ZigTypeIdArray);
+ continue;
+ } else if (target->type->id == ZigTypeIdPointer) {
+ // handle `[*]T`
+ // handle `[*c]T`
+ switch (target->data.x_ptr.special) {
+ case ConstPtrSpecialInvalid:
+ case ConstPtrSpecialDiscard:
+ zig_unreachable();
+ case ConstPtrSpecialRef:
+ target = target->data.x_ptr.data.ref.pointee;
+ assert(target->type->id == ZigTypeIdArray);
+ continue;
+ case ConstPtrSpecialBaseArray:
+ case ConstPtrSpecialSubArray:
+ target = target->data.x_ptr.data.base_array.array_val;
+ assert(target->type->id == ZigTypeIdArray);
+ continue;
+ case ConstPtrSpecialBaseStruct:
+ zig_panic("TODO slice const inner struct");
+ case ConstPtrSpecialBaseErrorUnionCode:
+ zig_panic("TODO slice const inner error union code");
+ case ConstPtrSpecialBaseErrorUnionPayload:
+ zig_panic("TODO slice const inner error union payload");
+ case ConstPtrSpecialBaseOptionalPayload:
+ zig_panic("TODO slice const inner optional payload");
+ case ConstPtrSpecialHardCodedAddr:
+ // skip check
+ goto exit_check_sentinel;
+ case ConstPtrSpecialFunction:
+ zig_panic("TODO slice of ptr cast from function");
+ case ConstPtrSpecialNull:
+ zig_panic("TODO slice of null ptr");
+ }
+ break;
+ } else if (is_slice(target->type)) {
+ // handle `[]T`
+ target = target->data.x_struct.fields[slice_ptr_index];
+ assert(target->type->id == ZigTypeIdPointer);
+ continue;
+ }
+
+ zig_unreachable();
+ }
+
+ // perform check
+ if (target_sentinel == nullptr) {
+ if (end_scalar >= target_len) {
+ ir_add_error(ira, &instruction->base.base, buf_sprintf("slice-sentinel is out of bounds"));
+ return ira->codegen->invalid_inst_gen;
+ }
+ if (!const_values_equal(ira->codegen, sentinel_val, &target_elements[end_scalar])) {
+ ir_add_error(ira, &instruction->base.base, buf_sprintf("slice-sentinel does not match memory at target index"));
+ return ira->codegen->invalid_inst_gen;
+ }
+ } else {
+ assert(end_scalar <= target_len);
+ if (end_scalar == target_len) {
+ if (!const_values_equal(ira->codegen, sentinel_val, target_sentinel)) {
+ ir_add_error(ira, &instruction->base.base, buf_sprintf("slice-sentinel does not match target-sentinel"));
+ return ira->codegen->invalid_inst_gen;
+ }
+ } else {
+ if (!const_values_equal(ira->codegen, sentinel_val, &target_elements[end_scalar])) {
+ ir_add_error(ira, &instruction->base.base, buf_sprintf("slice-sentinel does not match memory at target index"));
+ return ira->codegen->invalid_inst_gen;
+ }
+ }
+ }
+ }
+ exit_check_sentinel:
+
IrInstGen *result = ir_const(ira, &instruction->base.base, return_type);
ZigValue *ptr_val;
test/stage1/behavior/slice_sentinel_comptime.zig
@@ -0,0 +1,199 @@
+test "comptime slice-sentinel in bounds (unterminated)" {
+ // array
+ comptime {
+ var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ const slice = target[0..3 :'d'];
+ }
+
+ // ptr_array
+ comptime {
+ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ var target = &buf;
+ const slice = target[0..3 :'d'];
+ }
+
+ // vector_ConstPtrSpecialBaseArray
+ comptime {
+ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ var target: [*]u8 = &buf;
+ const slice = target[0..3 :'d'];
+ }
+
+ // vector_ConstPtrSpecialRef
+ comptime {
+ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ var target: [*]u8 = @ptrCast([*]u8, &buf);
+ const slice = target[0..3 :'d'];
+ }
+
+ // cvector_ConstPtrSpecialBaseArray
+ comptime {
+ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ var target: [*c]u8 = &buf;
+ const slice = target[0..3 :'d'];
+ }
+
+ // cvector_ConstPtrSpecialRef
+ comptime {
+ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ var target: [*c]u8 = @ptrCast([*c]u8, &buf);
+ const slice = target[0..3 :'d'];
+ }
+
+ // slice
+ comptime {
+ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ var target: []u8 = &buf;
+ const slice = target[0..3 :'d'];
+ }
+}
+
+test "comptime slice-sentinel in bounds (end,unterminated)" {
+ // array
+ comptime {
+ var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10;
+ const slice = target[0..13 :0xff];
+ }
+
+ // ptr_array
+ comptime {
+ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10;
+ var target = &buf;
+ const slice = target[0..13 :0xff];
+ }
+
+ // vector_ConstPtrSpecialBaseArray
+ comptime {
+ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10;
+ var target: [*]u8 = &buf;
+ const slice = target[0..13 :0xff];
+ }
+
+ // vector_ConstPtrSpecialRef
+ comptime {
+ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10;
+ var target: [*]u8 = @ptrCast([*]u8, &buf);
+ const slice = target[0..13 :0xff];
+ }
+
+ // cvector_ConstPtrSpecialBaseArray
+ comptime {
+ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10;
+ var target: [*c]u8 = &buf;
+ const slice = target[0..13 :0xff];
+ }
+
+ // cvector_ConstPtrSpecialRef
+ comptime {
+ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10;
+ var target: [*c]u8 = @ptrCast([*c]u8, &buf);
+ const slice = target[0..13 :0xff];
+ }
+
+ // slice
+ comptime {
+ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10;
+ var target: []u8 = &buf;
+ const slice = target[0..13 :0xff];
+ }
+}
+
+test "comptime slice-sentinel in bounds (terminated)" {
+ // array
+ comptime {
+ var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ const slice = target[0..3 :'d'];
+ }
+
+ // ptr_array
+ comptime {
+ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ var target = &buf;
+ const slice = target[0..3 :'d'];
+ }
+
+ // vector_ConstPtrSpecialBaseArray
+ comptime {
+ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ var target: [*]u8 = &buf;
+ const slice = target[0..3 :'d'];
+ }
+
+ // vector_ConstPtrSpecialRef
+ comptime {
+ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ var target: [*]u8 = @ptrCast([*]u8, &buf);
+ const slice = target[0..3 :'d'];
+ }
+
+ // cvector_ConstPtrSpecialBaseArray
+ comptime {
+ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ var target: [*c]u8 = &buf;
+ const slice = target[0..3 :'d'];
+ }
+
+ // cvector_ConstPtrSpecialRef
+ 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 :'d'];
+ }
+
+ // slice
+ comptime {
+ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ var target: []u8 = &buf;
+ const slice = target[0..3 :'d'];
+ }
+}
+
+test "comptime slice-sentinel in bounds (on target sentinel)" {
+ // array
+ comptime {
+ var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ const slice = target[0..14 :0];
+ }
+
+ // ptr_array
+ comptime {
+ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ var target = &buf;
+ const slice = target[0..14 :0];
+ }
+
+ // vector_ConstPtrSpecialBaseArray
+ comptime {
+ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ var target: [*]u8 = &buf;
+ const slice = target[0..14 :0];
+ }
+
+ // vector_ConstPtrSpecialRef
+ comptime {
+ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ var target: [*]u8 = @ptrCast([*]u8, &buf);
+ const slice = target[0..14 :0];
+ }
+
+ // cvector_ConstPtrSpecialBaseArray
+ comptime {
+ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ var target: [*c]u8 = &buf;
+ const slice = target[0..14 :0];
+ }
+
+ // cvector_ConstPtrSpecialRef
+ 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 :0];
+ }
+
+ // slice
+ comptime {
+ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ var target: []u8 = &buf;
+ const slice = target[0..14 :0];
+ }
+}
test/stage1/behavior.zig
@@ -96,6 +96,7 @@ comptime {
_ = @import("behavior/shuffle.zig");
_ = @import("behavior/sizeof_and_typeof.zig");
_ = @import("behavior/slice.zig");
+ _ = @import("behavior/slice_sentinel_comptime.zig");
_ = @import("behavior/struct.zig");
_ = @import("behavior/struct_contains_null_ptr_itself.zig");
_ = @import("behavior/struct_contains_slice_of_itself.zig");
test/compile_errors.zig
@@ -6857,4 +6857,299 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
"tmp.zig:7:32: error: destination type 'u16' has size 2 but source type '[]u8' has size 16",
"tmp.zig:7:37: note: referenced here",
});
+
+ cases.add("comptime slice-sentinel is out of bounds (unterminated)",
+ \\export fn foo_array() void {
+ \\ comptime {
+ \\ var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ \\ const slice = target[0..14 :0];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ , &[_][]const u8{
+ ":4:29: error: slice-sentinel is out of bounds",
+ ":11:29: error: slice-sentinel is out of bounds",
+ ":18:29: error: slice-sentinel is out of bounds",
+ ":25:29: error: slice-sentinel is out of bounds",
+ ":32:29: error: slice-sentinel is out of bounds",
+ ":39:29: error: slice-sentinel is out of bounds",
+ ":46:29: error: slice-sentinel is out of bounds",
+ });
+
+ cases.add("comptime slice-sentinel is out of bounds (terminated)",
+ \\export fn foo_array() void {
+ \\ comptime {
+ \\ var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ \\ const slice = target[0..15 :1];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ , &[_][]const u8{
+ ":4:29: error: out of bounds slice",
+ ":11:29: error: out of bounds slice",
+ ":18:29: error: out of bounds slice",
+ ":25:29: error: out of bounds slice",
+ ":32:29: error: out of bounds slice",
+ ":39:29: error: out of bounds slice",
+ ":46:29: error: out of bounds slice",
+ });
+
+ cases.add("comptime slice-sentinel does not match memory at target index (unterminated)",
+ \\export fn foo_array() void {
+ \\ comptime {
+ \\ var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ \\ const slice = target[0..3 :0];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ , &[_][]const u8{
+ ":4:29: error: slice-sentinel does not match memory at target index",
+ ":11:29: error: slice-sentinel does not match memory at target index",
+ ":18:29: error: slice-sentinel does not match memory at target index",
+ ":25:29: error: slice-sentinel does not match memory at target index",
+ ":32:29: error: slice-sentinel does not match memory at target index",
+ ":39:29: error: slice-sentinel does not match memory at target index",
+ ":46:29: error: slice-sentinel does not match memory at target index",
+ });
+
+ cases.add("comptime slice-sentinel does not match memory at target index (terminated)",
+ \\export fn foo_array() void {
+ \\ comptime {
+ \\ var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ \\ const slice = target[0..3 :0];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ , &[_][]const u8{
+ ":4:29: error: slice-sentinel does not match memory at target index",
+ ":11:29: error: slice-sentinel does not match memory at target index",
+ ":18:29: error: slice-sentinel does not match memory at target index",
+ ":25:29: error: slice-sentinel does not match memory at target index",
+ ":32:29: error: slice-sentinel does not match memory at target index",
+ ":39:29: error: slice-sentinel does not match memory at target index",
+ ":46:29: error: slice-sentinel does not match memory at target index",
+ });
+
+ cases.add("comptime slice-sentinel does not match target-sentinel",
+ \\export fn foo_array() void {
+ \\ comptime {
+ \\ var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
+ \\ const slice = target[0..14 :255];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ \\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];
+ \\ }
+ \\}
+ , &[_][]const u8{
+ ":4:29: error: slice-sentinel does not match target-sentinel",
+ ":11:29: error: slice-sentinel does not match target-sentinel",
+ ":18:29: error: slice-sentinel does not match target-sentinel",
+ ":25:29: error: slice-sentinel does not match target-sentinel",
+ ":32:29: error: slice-sentinel does not match target-sentinel",
+ ":39:29: error: slice-sentinel does not match target-sentinel",
+ ":46:29: error: slice-sentinel does not match target-sentinel",
+ });
}