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
This commit is contained in:
mlugg 2025-04-02 06:37:41 +01:00 committed by Alex Rønne Petersen
parent b5c22777f8
commit bee19572c8
No known key found for this signature in database
3 changed files with 47 additions and 0 deletions

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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