| author | |
| committer | |
| log | c1cc1ebc35f7a56669db2f88b6d4ff8f1603ec59 |
| tree | 17e1064c3d862df1bed5ea4f2e73d789afb1893f |
| parent | 8cad45349510b2995a49fc907bdc3c8bf86aa21b |
Constant-folding the pointers to the expected sentinel value have some
big problems: it hides the real content of the array, makes the pointer
to the sentinel point to a completely different memory region and treats
it like a const value even when the underlying array is mutable.
Fixes #48402 files changed, 16 insertions(+), 12 deletions(-)
src/ir.cpp+2-7| ... | @@ -20880,13 +20880,8 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP | ... | @@ -20880,13 +20880,8 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP |
| 20880 | if (instr_is_comptime(casted_elem_index)) { | 20880 | if (instr_is_comptime(casted_elem_index)) { |
| 20881 | uint64_t index = bigint_as_u64(&casted_elem_index->value->data.x_bigint); | 20881 | uint64_t index = bigint_as_u64(&casted_elem_index->value->data.x_bigint); |
| 20882 | if (array_type->id == ZigTypeIdArray) { | 20882 | if (array_type->id == ZigTypeIdArray) { |
| 20883 | uint64_t array_len = array_type->data.array.len; | 20883 | uint64_t array_len = array_type->data.array.len + |
| 20884 | if (index == array_len && array_type->data.array.sentinel != nullptr) { | 20884 | (array_type->data.array.sentinel != nullptr); |
| 20885 | ZigType *elem_type = array_type->data.array.child_type; | ||
| 20886 | IrInstGen *sentinel_elem = ir_const(ira, &elem_ptr_instruction->base.base, elem_type); | ||
| 20887 | copy_const_val(ira->codegen, sentinel_elem->value, array_type->data.array.sentinel); | ||
| 20888 | return ir_get_ref(ira, &elem_ptr_instruction->base.base, sentinel_elem, true, false); | ||
| 20889 | } | ||
| 20890 | if (index >= array_len) { | 20885 | if (index >= array_len) { |
| 20891 | ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, | 20886 | ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node, |
| 20892 | buf_sprintf("index %" ZIG_PRI_u64 " outside array of size %" ZIG_PRI_u64, | 20887 | buf_sprintf("index %" ZIG_PRI_u64 " outside array of size %" ZIG_PRI_u64, |
test/stage1/behavior/array.zig+14-5| ... | @@ -31,14 +31,23 @@ fn getArrayLen(a: []const u32) usize { | ... | @@ -31,14 +31,23 @@ fn getArrayLen(a: []const u32) usize { |
| 31 | test "array with sentinels" { | 31 | test "array with sentinels" { |
| 32 | const S = struct { | 32 | const S = struct { |
| 33 | fn doTheTest(is_ct: bool) void { | 33 | fn doTheTest(is_ct: bool) void { |
| 34 | var zero_sized: [0:0xde]u8 = [_:0xde]u8{}; | ||
| 35 | expectEqual(@as(u8, 0xde), zero_sized[0]); | ||
| 36 | // Disabled at runtime because of | ||
| 37 | // https://github.com/ziglang/zig/issues/4372 | ||
| 38 | if (is_ct) { | 34 | if (is_ct) { |
| 35 | var zero_sized: [0:0xde]u8 = [_:0xde]u8{}; | ||
| 36 | // Disabled at runtime because of | ||
| 37 | // https://github.com/ziglang/zig/issues/4372 | ||
| 38 | expectEqual(@as(u8, 0xde), zero_sized[0]); | ||
| 39 | var reinterpreted = @ptrCast(*[1]u8, &zero_sized); | 39 | var reinterpreted = @ptrCast(*[1]u8, &zero_sized); |
| 40 | expectEqual(@as(u8, 0xde), reinterpreted[0]); | 40 | expectEqual(@as(u8, 0xde), reinterpreted[0]); |
| 41 | } | 41 | } |
| 42 | var arr: [3:0x55]u8 = undefined; | ||
| 43 | // Make sure the sentinel pointer is pointing after the last element | ||
| 44 | if (!is_ct) { | ||
| 45 | const sentinel_ptr = @ptrToInt(&arr[3]); | ||
| 46 | const last_elem_ptr = @ptrToInt(&arr[2]); | ||
| 47 | expectEqual(@as(usize, 1), sentinel_ptr - last_elem_ptr); | ||
| 48 | } | ||
| 49 | // Make sure the sentinel is writeable | ||
| 50 | arr[3] = 0x55; | ||
| 42 | } | 51 | } |
| 43 | }; | 52 | }; |
| 44 | 53 | ||
| ... | @@ -372,7 +381,7 @@ test "access the null element of a null terminated array" { | ... | @@ -372,7 +381,7 @@ test "access the null element of a null terminated array" { |
| 372 | const S = struct { | 381 | const S = struct { |
| 373 | fn doTheTest() void { | 382 | fn doTheTest() void { |
| 374 | var array: [4:0]u8 = .{ 'a', 'o', 'e', 'u' }; | 383 | var array: [4:0]u8 = .{ 'a', 'o', 'e', 'u' }; |
| 375 | comptime expect(array[4] == 0); | 384 | expect(array[4] == 0); |
| 376 | var len: usize = 4; | 385 | var len: usize = 4; |
| 377 | expect(array[len] == 0); | 386 | expect(array[len] == 0); |
| 378 | } | 387 | } |