stage1: add compile errors for sentinel slicing

closes #3963
This commit is contained in:
Michael Dusan 2020-04-03 11:41:55 -04:00 committed by Andrew Kelley
parent f1425fd9da
commit db4c06ce60
4 changed files with 602 additions and 1 deletions

View file

@ -26583,7 +26583,6 @@ done_with_return_type:
if (parent_ptr == nullptr) if (parent_ptr == nullptr)
return ira->codegen->invalid_inst_gen; return ira->codegen->invalid_inst_gen;
if (parent_ptr->special == ConstValSpecialUndef) { if (parent_ptr->special == ConstValSpecialUndef) {
array_val = nullptr; array_val = nullptr;
abs_offset = 0; abs_offset = 0;
@ -26746,6 +26745,113 @@ done_with_return_type:
return ira->codegen->invalid_inst_gen; 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); IrInstGen *result = ir_const(ira, &instruction->base.base, return_type);
ZigValue *ptr_val; ZigValue *ptr_val;

View file

@ -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:32: error: destination type 'u16' has size 2 but source type '[]u8' has size 16",
"tmp.zig:7:37: note: referenced here", "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",
});
} }

View file

@ -96,6 +96,7 @@ comptime {
_ = @import("behavior/shuffle.zig"); _ = @import("behavior/shuffle.zig");
_ = @import("behavior/sizeof_and_typeof.zig"); _ = @import("behavior/sizeof_and_typeof.zig");
_ = @import("behavior/slice.zig"); _ = @import("behavior/slice.zig");
_ = @import("behavior/slice_sentinel_comptime.zig");
_ = @import("behavior/struct.zig"); _ = @import("behavior/struct.zig");
_ = @import("behavior/struct_contains_null_ptr_itself.zig"); _ = @import("behavior/struct_contains_null_ptr_itself.zig");
_ = @import("behavior/struct_contains_slice_of_itself.zig"); _ = @import("behavior/struct_contains_slice_of_itself.zig");

View file

@ -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];
}
}