diff --git a/src/Sema.zig b/src/Sema.zig index a686a3d8f2..354cb9e4d1 100644 --- 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 index e892918571..b8f81d74af 100644 --- 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 new file mode 100644 index 0000000000..4a2d475b1f --- /dev/null +++ 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