| author | |
| committer | |
| log | 4ec299007a6a183edddfcb0505a9c1501da7ad0c |
| tree | 147976e4d469e4e494244bb86111b73aaeb7bd11 |
| parent | 68c7261e1daf7787dcbf0cd6f9b01e5678d20a93 |
It doesn't matter if a pointer to a zero-bit (i.e. OPV) type is
undefined or runtime-known; we still know the result of the dereference
at comptime. Code may use this, for instance, when allocating zero-bit
types: `@as(*void, undefined)` is entirely reasonable to use at runtime,
since we know the pointer will never be accessed, thus it should be
valid at comptime too.2 files changed, 13 insertions(+), 0 deletions(-)
src/Sema.zig+5| ... | ... | @@ -4712,6 +4712,11 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr |
| 4712 | 4712 | .Slice => return sema.fail(block, src, "index syntax required for slice type '{}'", .{operand_ty.fmt(sema.mod)}), |
| 4713 | 4713 | } |
| 4714 | 4714 | |
| 4715 | if ((try sema.typeHasOnePossibleValue(operand_ty.childType())) != null) { | |
| 4716 | // No need to validate the actual pointer value, we don't need it! | |
| 4717 | return; | |
| 4718 | } | |
| 4719 | ||
| 4715 | 4720 | const elem_ty = operand_ty.elemType2(); |
| 4716 | 4721 | if (try sema.resolveMaybeUndefVal(operand)) |val| { |
| 4717 | 4722 | if (val.isUndef()) { |
test/behavior/comptime_memory.zig+8| ... | ... | @@ -420,3 +420,11 @@ test "mutate entire slice at comptime" { |
| 420 | 420 | buf[1..3].* = x; |
| 421 | 421 | } |
| 422 | 422 | } |
| 423 | ||
| 424 | test "dereference undefined pointer to zero-bit type" { | |
| 425 | const p0: *void = undefined; | |
| 426 | try testing.expectEqual({}, p0.*); | |
| 427 | ||
| 428 | const p1: *[0]u32 = undefined; | |
| 429 | try testing.expect(p1.*.len == 0); | |
| 430 | } |