| author | |
| committer | |
| log | bee19572c83c77995ca9a1206a6b08606f65eaa7 |
| tree | d5f98142584f04be404c35a338008d0f0528f8dc |
| parent | b5c22777f839f926ff3e272c9285d4d3e6402c0d |
| signature |
* Indexing zero-bit types should not produce AIR indexing instructions
* Getting a runtime-known element pointer from a many-pointer should
check that the many-pointer is not comptime-only
Resolves: #234053 files changed, 47 insertions(+), 0 deletions(-)
src/Sema.zig+13| ... | ... | @@ -29037,6 +29037,14 @@ fn elemPtrOneLayerOnly( |
| 29037 | 29037 | } |
| 29038 | 29038 | const result_ty = try indexable_ty.elemPtrType(null, pt); |
| 29039 | 29039 | |
| 29040 | try sema.validateRuntimeElemAccess(block, elem_index_src, result_ty, indexable_ty, indexable_src); | |
| 29041 | try sema.validateRuntimeValue(block, indexable_src, indexable); | |
| 29042 | ||
| 29043 | if (!try result_ty.childType(zcu).hasRuntimeBitsIgnoreComptimeSema(pt)) { | |
| 29044 | // zero-bit child type; just bitcast the pointer | |
| 29045 | return block.addBitCast(result_ty, indexable); | |
| 29046 | } | |
| 29047 | ||
| 29040 | 29048 | return block.addPtrElemPtr(indexable, elem_index, result_ty); |
| 29041 | 29049 | }, |
| 29042 | 29050 | .one => { |
| ... | ... | @@ -29497,6 +29505,11 @@ fn elemPtrSlice( |
| 29497 | 29505 | const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt; |
| 29498 | 29506 | try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op); |
| 29499 | 29507 | } |
| 29508 | if (!try slice_ty.childType(zcu).hasRuntimeBitsIgnoreComptimeSema(pt)) { | |
| 29509 | // zero-bit child type; just extract the pointer and bitcast it | |
| 29510 | const slice_ptr = try block.addTyOp(.slice_ptr, slice_ty.slicePtrFieldType(zcu), slice); | |
| 29511 | return block.addBitCast(elem_ptr_ty, slice_ptr); | |
| 29512 | } | |
| 29500 | 29513 | return block.addSliceElemPtr(slice, elem_index, elem_ptr_ty); |
| 29501 | 29514 | } |
| 29502 | 29515 |
test/behavior/pointers.zig+24| ... | ... | @@ -760,3 +760,27 @@ test "comptime pointer equality through distinct elements with well-defined layo |
| 760 | 760 | comptime assert(buf[1] == 456); |
| 761 | 761 | comptime assert(second_elem.* == 456); |
| 762 | 762 | } |
| 763 | ||
| 764 | test "pointers to elements of slice of zero-bit type" { | |
| 765 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | |
| 766 | ||
| 767 | var slice: []const u0 = undefined; | |
| 768 | slice = &.{ 0, 0 }; | |
| 769 | ||
| 770 | const a = &slice[0]; | |
| 771 | const b = &slice[1]; | |
| 772 | ||
| 773 | try expect(a == b); | |
| 774 | } | |
| 775 | ||
| 776 | test "pointers to elements of many-ptr to zero-bit type" { | |
| 777 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | |
| 778 | ||
| 779 | var many_ptr: [*]const u0 = undefined; | |
| 780 | many_ptr = &.{ 0, 0 }; | |
| 781 | ||
| 782 | const a = &many_ptr[0]; | |
| 783 | const b = &many_ptr[1]; | |
| 784 | ||
| 785 | try expect(a == b); | |
| 786 | } |
test/cases/compile_errors/runtime_index_into_comptime_only_many_ptr.zig created+10| ... | ... | @@ -0,0 +1,10 @@ |
| 1 | var rt: usize = 0; | |
| 2 | export fn foo() void { | |
| 3 | const x: [*]const type = &.{ u8, u16 }; | |
| 4 | _ = &x[rt]; | |
| 5 | } | |
| 6 | ||
| 7 | // error | |
| 8 | // | |
| 9 | // :4:12: error: values of type '[*]const type' must be comptime-known, but index value is runtime-known | |
| 10 | // :4:11: note: types are not available at runtime |