zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit bee19572c83c77995ca9a1206a6b08606f65eaa7 (tree)
parent b5c22777f839f926ff3e272c9285d4d3e6402c0d
Author: mlugg <mlugg@mlugg.co.uk>
Date:   Wed,  2 Apr 2025 06:37:41 +0100

Sema: fix a few indexing bugs

* 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: #23405

Diffstat:
Msrc/Sema.zig | 13+++++++++++++
Mtest/behavior/pointers.zig | 24++++++++++++++++++++++++
Atest/cases/compile_errors/runtime_index_into_comptime_only_many_ptr.zig | 10++++++++++
3 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/src/Sema.zig b/src/Sema.zig @@ -29037,6 +29037,14 @@ fn elemPtrOneLayerOnly( } const result_ty = try indexable_ty.elemPtrType(null, pt); + try sema.validateRuntimeElemAccess(block, elem_index_src, result_ty, indexable_ty, indexable_src); + try sema.validateRuntimeValue(block, indexable_src, indexable); + + if (!try result_ty.childType(zcu).hasRuntimeBitsIgnoreComptimeSema(pt)) { + // zero-bit child type; just bitcast the pointer + return block.addBitCast(result_ty, indexable); + } + return block.addPtrElemPtr(indexable, elem_index, result_ty); }, .one => { @@ -29497,6 +29505,11 @@ fn elemPtrSlice( const cmp_op: Air.Inst.Tag = if (slice_sent) .cmp_lte else .cmp_lt; try sema.addSafetyCheckIndexOob(block, src, elem_index, len_inst, cmp_op); } + if (!try slice_ty.childType(zcu).hasRuntimeBitsIgnoreComptimeSema(pt)) { + // zero-bit child type; just extract the pointer and bitcast it + const slice_ptr = try block.addTyOp(.slice_ptr, slice_ty.slicePtrFieldType(zcu), slice); + return block.addBitCast(elem_ptr_ty, slice_ptr); + } return block.addSliceElemPtr(slice, elem_index, elem_ptr_ty); } diff --git a/test/behavior/pointers.zig b/test/behavior/pointers.zig @@ -760,3 +760,27 @@ test "comptime pointer equality through distinct elements with well-defined layo comptime assert(buf[1] == 456); comptime assert(second_elem.* == 456); } + +test "pointers to elements of slice of zero-bit type" { + if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; + + var slice: []const u0 = undefined; + slice = &.{ 0, 0 }; + + const a = &slice[0]; + const b = &slice[1]; + + try expect(a == b); +} + +test "pointers to elements of many-ptr to zero-bit type" { + if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; + + var many_ptr: [*]const u0 = undefined; + many_ptr = &.{ 0, 0 }; + + const a = &many_ptr[0]; + const b = &many_ptr[1]; + + try expect(a == b); +} diff --git a/test/cases/compile_errors/runtime_index_into_comptime_only_many_ptr.zig b/test/cases/compile_errors/runtime_index_into_comptime_only_many_ptr.zig @@ -0,0 +1,10 @@ +var rt: usize = 0; +export fn foo() void { + const x: [*]const type = &.{ u8, u16 }; + _ = &x[rt]; +} + +// error +// +// :4:12: error: values of type '[*]const type' must be comptime-known, but index value is runtime-known +// :4:11: note: types are not available at runtime