authorgravatar for michael.dusan@gmail.comMichael Dusan <michael.dusan@gmail.com> 2020-04-03 11:41:55-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-04-03 19:05:30-04:00
logdb4c06ce606dcfe989b5c1f76d5ed00e90d5dd9f
tree9feedf90f8670da85296ca253c7f79053a87c839
parentf1425fd9da1b2e1297a36108b12b0bd89398b057

stage1: add compile errors for sentinel slicing

closes #3963

4 files changed, 602 insertions(+), 1 deletions(-)

src/ir.cpp+107-1
...@@ -26583,7 +26583,6 @@ done_with_return_type:...@@ -26583,7 +26583,6 @@ done_with_return_type:
26583 if (parent_ptr == nullptr)26583 if (parent_ptr == nullptr)
26584 return ira->codegen->invalid_inst_gen;26584 return ira->codegen->invalid_inst_gen;
2658526585
26586
26587 if (parent_ptr->special == ConstValSpecialUndef) {26586 if (parent_ptr->special == ConstValSpecialUndef) {
26588 array_val = nullptr;26587 array_val = nullptr;
26589 abs_offset = 0;26588 abs_offset = 0;
...@@ -26746,6 +26745,113 @@ done_with_return_type:...@@ -26746,6 +26745,113 @@ done_with_return_type:
26746 return ira->codegen->invalid_inst_gen;26745 return ira->codegen->invalid_inst_gen;
26747 }26746 }
2674826747
26748 // check sentinel when target is comptime-known
26749 {
26750 if (!sentinel_val)
26751 goto exit_check_sentinel;
26752
26753 switch (ptr_ptr->value->data.x_ptr.mut) {
26754 case ConstPtrMutComptimeConst:
26755 case ConstPtrMutComptimeVar:
26756 break;
26757 case ConstPtrMutRuntimeVar:
26758 case ConstPtrMutInfer:
26759 goto exit_check_sentinel;
26760 }
26761
26762 // prepare check parameters
26763 ZigValue *target = const_ptr_pointee(ira, ira->codegen, ptr_ptr->value, instruction->base.base.source_node);
26764 if (target == nullptr)
26765 return ira->codegen->invalid_inst_gen;
26766
26767 uint64_t target_len = 0;
26768 ZigValue *target_sentinel = nullptr;
26769 ZigValue *target_elements = nullptr;
26770
26771 for (;;) {
26772 if (target->type->id == ZigTypeIdArray) {
26773 // handle `[N]T`
26774 target_len = target->type->data.array.len;
26775 target_sentinel = target->type->data.array.sentinel;
26776 target_elements = target->data.x_array.data.s_none.elements;
26777 break;
26778 } else if (target->type->id == ZigTypeIdPointer && target->type->data.pointer.child_type->id == ZigTypeIdArray) {
26779 // handle `*[N]T`
26780 target = const_ptr_pointee(ira, ira->codegen, target, instruction->base.base.source_node);
26781 if (target == nullptr)
26782 return ira->codegen->invalid_inst_gen;
26783 assert(target->type->id == ZigTypeIdArray);
26784 continue;
26785 } else if (target->type->id == ZigTypeIdPointer) {
26786 // handle `[*]T`
26787 // handle `[*c]T`
26788 switch (target->data.x_ptr.special) {
26789 case ConstPtrSpecialInvalid:
26790 case ConstPtrSpecialDiscard:
26791 zig_unreachable();
26792 case ConstPtrSpecialRef:
26793 target = target->data.x_ptr.data.ref.pointee;
26794 assert(target->type->id == ZigTypeIdArray);
26795 continue;
26796 case ConstPtrSpecialBaseArray:
26797 case ConstPtrSpecialSubArray:
26798 target = target->data.x_ptr.data.base_array.array_val;
26799 assert(target->type->id == ZigTypeIdArray);
26800 continue;
26801 case ConstPtrSpecialBaseStruct:
26802 zig_panic("TODO slice const inner struct");
26803 case ConstPtrSpecialBaseErrorUnionCode:
26804 zig_panic("TODO slice const inner error union code");
26805 case ConstPtrSpecialBaseErrorUnionPayload:
26806 zig_panic("TODO slice const inner error union payload");
26807 case ConstPtrSpecialBaseOptionalPayload:
26808 zig_panic("TODO slice const inner optional payload");
26809 case ConstPtrSpecialHardCodedAddr:
26810 // skip check
26811 goto exit_check_sentinel;
26812 case ConstPtrSpecialFunction:
26813 zig_panic("TODO slice of ptr cast from function");
26814 case ConstPtrSpecialNull:
26815 zig_panic("TODO slice of null ptr");
26816 }
26817 break;
26818 } else if (is_slice(target->type)) {
26819 // handle `[]T`
26820 target = target->data.x_struct.fields[slice_ptr_index];
26821 assert(target->type->id == ZigTypeIdPointer);
26822 continue;
26823 }
26824
26825 zig_unreachable();
26826 }
26827
26828 // perform check
26829 if (target_sentinel == nullptr) {
26830 if (end_scalar >= target_len) {
26831 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice-sentinel is out of bounds"));
26832 return ira->codegen->invalid_inst_gen;
26833 }
26834 if (!const_values_equal(ira->codegen, sentinel_val, &target_elements[end_scalar])) {
26835 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice-sentinel does not match memory at target index"));
26836 return ira->codegen->invalid_inst_gen;
26837 }
26838 } else {
26839 assert(end_scalar <= target_len);
26840 if (end_scalar == target_len) {
26841 if (!const_values_equal(ira->codegen, sentinel_val, target_sentinel)) {
26842 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice-sentinel does not match target-sentinel"));
26843 return ira->codegen->invalid_inst_gen;
26844 }
26845 } else {
26846 if (!const_values_equal(ira->codegen, sentinel_val, &target_elements[end_scalar])) {
26847 ir_add_error(ira, &instruction->base.base, buf_sprintf("slice-sentinel does not match memory at target index"));
26848 return ira->codegen->invalid_inst_gen;
26849 }
26850 }
26851 }
26852 }
26853 exit_check_sentinel:
26854
26749 IrInstGen *result = ir_const(ira, &instruction->base.base, return_type);26855 IrInstGen *result = ir_const(ira, &instruction->base.base, return_type);
2675026856
26751 ZigValue *ptr_val;26857 ZigValue *ptr_val;
test/compile_errors.zig+295
...@@ -6857,4 +6857,299 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6857,4 +6857,299 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6857 "tmp.zig:7:32: error: destination type 'u16' has size 2 but source type '[]u8' has size 16",6857 "tmp.zig:7:32: error: destination type 'u16' has size 2 but source type '[]u8' has size 16",
6858 "tmp.zig:7:37: note: referenced here",6858 "tmp.zig:7:37: note: referenced here",
6859 });6859 });
6860
6861 cases.add("comptime slice-sentinel is out of bounds (unterminated)",
6862 \\export fn foo_array() void {
6863 \\ comptime {
6864 \\ var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
6865 \\ const slice = target[0..14 :0];
6866 \\ }
6867 \\}
6868 \\export fn foo_ptr_array() void {
6869 \\ comptime {
6870 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
6871 \\ var target = &buf;
6872 \\ const slice = target[0..14 :0];
6873 \\ }
6874 \\}
6875 \\export fn foo_vector_ConstPtrSpecialBaseArray() void {
6876 \\ comptime {
6877 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
6878 \\ var target: [*]u8 = &buf;
6879 \\ const slice = target[0..14 :0];
6880 \\ }
6881 \\}
6882 \\export fn foo_vector_ConstPtrSpecialRef() void {
6883 \\ comptime {
6884 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
6885 \\ var target: [*]u8 = @ptrCast([*]u8, &buf);
6886 \\ const slice = target[0..14 :0];
6887 \\ }
6888 \\}
6889 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void {
6890 \\ comptime {
6891 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
6892 \\ var target: [*c]u8 = &buf;
6893 \\ const slice = target[0..14 :0];
6894 \\ }
6895 \\}
6896 \\export fn foo_cvector_ConstPtrSpecialRef() void {
6897 \\ comptime {
6898 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
6899 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf);
6900 \\ const slice = target[0..14 :0];
6901 \\ }
6902 \\}
6903 \\export fn foo_slice() void {
6904 \\ comptime {
6905 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
6906 \\ var target: []u8 = &buf;
6907 \\ const slice = target[0..14 :0];
6908 \\ }
6909 \\}
6910 , &[_][]const u8{
6911 ":4:29: error: slice-sentinel is out of bounds",
6912 ":11:29: error: slice-sentinel is out of bounds",
6913 ":18:29: error: slice-sentinel is out of bounds",
6914 ":25:29: error: slice-sentinel is out of bounds",
6915 ":32:29: error: slice-sentinel is out of bounds",
6916 ":39:29: error: slice-sentinel is out of bounds",
6917 ":46:29: error: slice-sentinel is out of bounds",
6918 });
6919
6920 cases.add("comptime slice-sentinel is out of bounds (terminated)",
6921 \\export fn foo_array() void {
6922 \\ comptime {
6923 \\ var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
6924 \\ const slice = target[0..15 :1];
6925 \\ }
6926 \\}
6927 \\export fn foo_ptr_array() void {
6928 \\ comptime {
6929 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
6930 \\ var target = &buf;
6931 \\ const slice = target[0..15 :0];
6932 \\ }
6933 \\}
6934 \\export fn foo_vector_ConstPtrSpecialBaseArray() void {
6935 \\ comptime {
6936 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
6937 \\ var target: [*]u8 = &buf;
6938 \\ const slice = target[0..15 :0];
6939 \\ }
6940 \\}
6941 \\export fn foo_vector_ConstPtrSpecialRef() void {
6942 \\ comptime {
6943 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
6944 \\ var target: [*]u8 = @ptrCast([*]u8, &buf);
6945 \\ const slice = target[0..15 :0];
6946 \\ }
6947 \\}
6948 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void {
6949 \\ comptime {
6950 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
6951 \\ var target: [*c]u8 = &buf;
6952 \\ const slice = target[0..15 :0];
6953 \\ }
6954 \\}
6955 \\export fn foo_cvector_ConstPtrSpecialRef() void {
6956 \\ comptime {
6957 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
6958 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf);
6959 \\ const slice = target[0..15 :0];
6960 \\ }
6961 \\}
6962 \\export fn foo_slice() void {
6963 \\ comptime {
6964 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
6965 \\ var target: []u8 = &buf;
6966 \\ const slice = target[0..15 :0];
6967 \\ }
6968 \\}
6969 , &[_][]const u8{
6970 ":4:29: error: out of bounds slice",
6971 ":11:29: error: out of bounds slice",
6972 ":18:29: error: out of bounds slice",
6973 ":25:29: error: out of bounds slice",
6974 ":32:29: error: out of bounds slice",
6975 ":39:29: error: out of bounds slice",
6976 ":46:29: error: out of bounds slice",
6977 });
6978
6979 cases.add("comptime slice-sentinel does not match memory at target index (unterminated)",
6980 \\export fn foo_array() void {
6981 \\ comptime {
6982 \\ var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
6983 \\ const slice = target[0..3 :0];
6984 \\ }
6985 \\}
6986 \\export fn foo_ptr_array() void {
6987 \\ comptime {
6988 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
6989 \\ var target = &buf;
6990 \\ const slice = target[0..3 :0];
6991 \\ }
6992 \\}
6993 \\export fn foo_vector_ConstPtrSpecialBaseArray() void {
6994 \\ comptime {
6995 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
6996 \\ var target: [*]u8 = &buf;
6997 \\ const slice = target[0..3 :0];
6998 \\ }
6999 \\}
7000 \\export fn foo_vector_ConstPtrSpecialRef() void {
7001 \\ comptime {
7002 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
7003 \\ var target: [*]u8 = @ptrCast([*]u8, &buf);
7004 \\ const slice = target[0..3 :0];
7005 \\ }
7006 \\}
7007 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void {
7008 \\ comptime {
7009 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
7010 \\ var target: [*c]u8 = &buf;
7011 \\ const slice = target[0..3 :0];
7012 \\ }
7013 \\}
7014 \\export fn foo_cvector_ConstPtrSpecialRef() void {
7015 \\ comptime {
7016 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
7017 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf);
7018 \\ const slice = target[0..3 :0];
7019 \\ }
7020 \\}
7021 \\export fn foo_slice() void {
7022 \\ comptime {
7023 \\ var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
7024 \\ var target: []u8 = &buf;
7025 \\ const slice = target[0..3 :0];
7026 \\ }
7027 \\}
7028 , &[_][]const u8{
7029 ":4:29: error: slice-sentinel does not match memory at target index",
7030 ":11:29: error: slice-sentinel does not match memory at target index",
7031 ":18:29: error: slice-sentinel does not match memory at target index",
7032 ":25:29: error: slice-sentinel does not match memory at target index",
7033 ":32:29: error: slice-sentinel does not match memory at target index",
7034 ":39:29: error: slice-sentinel does not match memory at target index",
7035 ":46:29: error: slice-sentinel does not match memory at target index",
7036 });
7037
7038 cases.add("comptime slice-sentinel does not match memory at target index (terminated)",
7039 \\export fn foo_array() void {
7040 \\ comptime {
7041 \\ var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
7042 \\ const slice = target[0..3 :0];
7043 \\ }
7044 \\}
7045 \\export fn foo_ptr_array() void {
7046 \\ comptime {
7047 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
7048 \\ var target = &buf;
7049 \\ const slice = target[0..3 :0];
7050 \\ }
7051 \\}
7052 \\export fn foo_vector_ConstPtrSpecialBaseArray() void {
7053 \\ comptime {
7054 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
7055 \\ var target: [*]u8 = &buf;
7056 \\ const slice = target[0..3 :0];
7057 \\ }
7058 \\}
7059 \\export fn foo_vector_ConstPtrSpecialRef() void {
7060 \\ comptime {
7061 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
7062 \\ var target: [*]u8 = @ptrCast([*]u8, &buf);
7063 \\ const slice = target[0..3 :0];
7064 \\ }
7065 \\}
7066 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void {
7067 \\ comptime {
7068 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
7069 \\ var target: [*c]u8 = &buf;
7070 \\ const slice = target[0..3 :0];
7071 \\ }
7072 \\}
7073 \\export fn foo_cvector_ConstPtrSpecialRef() void {
7074 \\ comptime {
7075 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
7076 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf);
7077 \\ const slice = target[0..3 :0];
7078 \\ }
7079 \\}
7080 \\export fn foo_slice() void {
7081 \\ comptime {
7082 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
7083 \\ var target: []u8 = &buf;
7084 \\ const slice = target[0..3 :0];
7085 \\ }
7086 \\}
7087 , &[_][]const u8{
7088 ":4:29: error: slice-sentinel does not match memory at target index",
7089 ":11:29: error: slice-sentinel does not match memory at target index",
7090 ":18:29: error: slice-sentinel does not match memory at target index",
7091 ":25:29: error: slice-sentinel does not match memory at target index",
7092 ":32:29: error: slice-sentinel does not match memory at target index",
7093 ":39:29: error: slice-sentinel does not match memory at target index",
7094 ":46:29: error: slice-sentinel does not match memory at target index",
7095 });
7096
7097 cases.add("comptime slice-sentinel does not match target-sentinel",
7098 \\export fn foo_array() void {
7099 \\ comptime {
7100 \\ var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
7101 \\ const slice = target[0..14 :255];
7102 \\ }
7103 \\}
7104 \\export fn foo_ptr_array() void {
7105 \\ comptime {
7106 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
7107 \\ var target = &buf;
7108 \\ const slice = target[0..14 :255];
7109 \\ }
7110 \\}
7111 \\export fn foo_vector_ConstPtrSpecialBaseArray() void {
7112 \\ comptime {
7113 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
7114 \\ var target: [*]u8 = &buf;
7115 \\ const slice = target[0..14 :255];
7116 \\ }
7117 \\}
7118 \\export fn foo_vector_ConstPtrSpecialRef() void {
7119 \\ comptime {
7120 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
7121 \\ var target: [*]u8 = @ptrCast([*]u8, &buf);
7122 \\ const slice = target[0..14 :255];
7123 \\ }
7124 \\}
7125 \\export fn foo_cvector_ConstPtrSpecialBaseArray() void {
7126 \\ comptime {
7127 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
7128 \\ var target: [*c]u8 = &buf;
7129 \\ const slice = target[0..14 :255];
7130 \\ }
7131 \\}
7132 \\export fn foo_cvector_ConstPtrSpecialRef() void {
7133 \\ comptime {
7134 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
7135 \\ var target: [*c]u8 = @ptrCast([*c]u8, &buf);
7136 \\ const slice = target[0..14 :255];
7137 \\ }
7138 \\}
7139 \\export fn foo_slice() void {
7140 \\ comptime {
7141 \\ var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
7142 \\ var target: []u8 = &buf;
7143 \\ const slice = target[0..14 :255];
7144 \\ }
7145 \\}
7146 , &[_][]const u8{
7147 ":4:29: error: slice-sentinel does not match target-sentinel",
7148 ":11:29: error: slice-sentinel does not match target-sentinel",
7149 ":18:29: error: slice-sentinel does not match target-sentinel",
7150 ":25:29: error: slice-sentinel does not match target-sentinel",
7151 ":32:29: error: slice-sentinel does not match target-sentinel",
7152 ":39:29: error: slice-sentinel does not match target-sentinel",
7153 ":46:29: error: slice-sentinel does not match target-sentinel",
7154 });
6860}7155}
test/stage1/behavior.zig+1
...@@ -96,6 +96,7 @@ comptime {...@@ -96,6 +96,7 @@ comptime {
96 _ = @import("behavior/shuffle.zig");96 _ = @import("behavior/shuffle.zig");
97 _ = @import("behavior/sizeof_and_typeof.zig");97 _ = @import("behavior/sizeof_and_typeof.zig");
98 _ = @import("behavior/slice.zig");98 _ = @import("behavior/slice.zig");
99 _ = @import("behavior/slice_sentinel_comptime.zig");
99 _ = @import("behavior/struct.zig");100 _ = @import("behavior/struct.zig");
100 _ = @import("behavior/struct_contains_null_ptr_itself.zig");101 _ = @import("behavior/struct_contains_null_ptr_itself.zig");
101 _ = @import("behavior/struct_contains_slice_of_itself.zig");102 _ = @import("behavior/struct_contains_slice_of_itself.zig");
test/stage1/behavior/slice_sentinel_comptime.zig created+199
...@@ -0,0 +1,199 @@
1test "comptime slice-sentinel in bounds (unterminated)" {
2 // array
3 comptime {
4 var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
5 const slice = target[0..3 :'d'];
6 }
7
8 // ptr_array
9 comptime {
10 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
11 var target = &buf;
12 const slice = target[0..3 :'d'];
13 }
14
15 // vector_ConstPtrSpecialBaseArray
16 comptime {
17 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
18 var target: [*]u8 = &buf;
19 const slice = target[0..3 :'d'];
20 }
21
22 // vector_ConstPtrSpecialRef
23 comptime {
24 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
25 var target: [*]u8 = @ptrCast([*]u8, &buf);
26 const slice = target[0..3 :'d'];
27 }
28
29 // cvector_ConstPtrSpecialBaseArray
30 comptime {
31 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
32 var target: [*c]u8 = &buf;
33 const slice = target[0..3 :'d'];
34 }
35
36 // cvector_ConstPtrSpecialRef
37 comptime {
38 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
39 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
40 const slice = target[0..3 :'d'];
41 }
42
43 // slice
44 comptime {
45 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
46 var target: []u8 = &buf;
47 const slice = target[0..3 :'d'];
48 }
49}
50
51test "comptime slice-sentinel in bounds (end,unterminated)" {
52 // array
53 comptime {
54 var target = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10;
55 const slice = target[0..13 :0xff];
56 }
57
58 // ptr_array
59 comptime {
60 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10;
61 var target = &buf;
62 const slice = target[0..13 :0xff];
63 }
64
65 // vector_ConstPtrSpecialBaseArray
66 comptime {
67 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10;
68 var target: [*]u8 = &buf;
69 const slice = target[0..13 :0xff];
70 }
71
72 // vector_ConstPtrSpecialRef
73 comptime {
74 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10;
75 var target: [*]u8 = @ptrCast([*]u8, &buf);
76 const slice = target[0..13 :0xff];
77 }
78
79 // cvector_ConstPtrSpecialBaseArray
80 comptime {
81 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10;
82 var target: [*c]u8 = &buf;
83 const slice = target[0..13 :0xff];
84 }
85
86 // cvector_ConstPtrSpecialRef
87 comptime {
88 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10;
89 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
90 const slice = target[0..13 :0xff];
91 }
92
93 // slice
94 comptime {
95 var buf = [_]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{0xff} ** 10;
96 var target: []u8 = &buf;
97 const slice = target[0..13 :0xff];
98 }
99}
100
101test "comptime slice-sentinel in bounds (terminated)" {
102 // array
103 comptime {
104 var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
105 const slice = target[0..3 :'d'];
106 }
107
108 // ptr_array
109 comptime {
110 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
111 var target = &buf;
112 const slice = target[0..3 :'d'];
113 }
114
115 // vector_ConstPtrSpecialBaseArray
116 comptime {
117 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
118 var target: [*]u8 = &buf;
119 const slice = target[0..3 :'d'];
120 }
121
122 // vector_ConstPtrSpecialRef
123 comptime {
124 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
125 var target: [*]u8 = @ptrCast([*]u8, &buf);
126 const slice = target[0..3 :'d'];
127 }
128
129 // cvector_ConstPtrSpecialBaseArray
130 comptime {
131 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
132 var target: [*c]u8 = &buf;
133 const slice = target[0..3 :'d'];
134 }
135
136 // cvector_ConstPtrSpecialRef
137 comptime {
138 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
139 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
140 const slice = target[0..3 :'d'];
141 }
142
143 // slice
144 comptime {
145 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
146 var target: []u8 = &buf;
147 const slice = target[0..3 :'d'];
148 }
149}
150
151test "comptime slice-sentinel in bounds (on target sentinel)" {
152 // array
153 comptime {
154 var target = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
155 const slice = target[0..14 :0];
156 }
157
158 // ptr_array
159 comptime {
160 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
161 var target = &buf;
162 const slice = target[0..14 :0];
163 }
164
165 // vector_ConstPtrSpecialBaseArray
166 comptime {
167 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
168 var target: [*]u8 = &buf;
169 const slice = target[0..14 :0];
170 }
171
172 // vector_ConstPtrSpecialRef
173 comptime {
174 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
175 var target: [*]u8 = @ptrCast([*]u8, &buf);
176 const slice = target[0..14 :0];
177 }
178
179 // cvector_ConstPtrSpecialBaseArray
180 comptime {
181 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
182 var target: [*c]u8 = &buf;
183 const slice = target[0..14 :0];
184 }
185
186 // cvector_ConstPtrSpecialRef
187 comptime {
188 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
189 var target: [*c]u8 = @ptrCast([*c]u8, &buf);
190 const slice = target[0..14 :0];
191 }
192
193 // slice
194 comptime {
195 var buf = [_:0]u8{ 'a', 'b', 'c', 'd' } ++ [_]u8{undefined} ** 10;
196 var target: []u8 = &buf;
197 const slice = target[0..14 :0];
198 }
199}