From 5f3a70ed5f5fe21eaaff0a06e95287a13fd2272d Mon Sep 17 00:00:00 2001 From: xdBronch <51252236+xdBronch@users.noreply.github.com> Date: Mon, 18 Nov 2024 16:35:45 -0500 Subject: [PATCH] Fix peer type resolution with allowzero pointers --- src/Sema.zig | 1 + test/behavior/cast.zig | 62 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index 70212e0a63..0424970f18 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -35076,6 +35076,7 @@ fn resolvePeerTypesInner( ptr_info.flags.is_const = ptr_info.flags.is_const or peer_info.flags.is_const; ptr_info.flags.is_volatile = ptr_info.flags.is_volatile or peer_info.flags.is_volatile; + ptr_info.flags.is_allowzero = ptr_info.flags.is_allowzero or peer_info.flags.is_allowzero; const peer_sentinel: InternPool.Index = switch (peer_info.flags.size) { .One => switch (ip.indexToKey(peer_info.child)) { diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index 3a9b5157a4..50e13a355b 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -2200,39 +2200,77 @@ test "peer type resolution: pointer attributes are combined correctly" { var buf_a align(4) = "foo".*; var buf_b align(4) = "bar".*; var buf_c align(4) = "baz".*; + var buf_d align(4) = "qux".*; const a: [*:0]align(4) const u8 = &buf_a; const b: *align(2) volatile [3:0]u8 = &buf_b; const c: [*:0]align(4) u8 = &buf_c; + const d: [*:0]allowzero align(4) u8 = &buf_d; - comptime assert(@TypeOf(a, b, c) == [*:0]align(2) const volatile u8); - comptime assert(@TypeOf(a, c, b) == [*:0]align(2) const volatile u8); - comptime assert(@TypeOf(b, a, c) == [*:0]align(2) const volatile u8); - comptime assert(@TypeOf(b, c, a) == [*:0]align(2) const volatile u8); - comptime assert(@TypeOf(c, a, b) == [*:0]align(2) const volatile u8); - comptime assert(@TypeOf(c, b, a) == [*:0]align(2) const volatile u8); + comptime assert(@TypeOf(a, b, c, d) == [*:0]allowzero align(2) const volatile u8); + comptime assert(@TypeOf(a, b, d, c) == [*:0]allowzero align(2) const volatile u8); + comptime assert(@TypeOf(a, c, b, d) == [*:0]allowzero align(2) const volatile u8); + comptime assert(@TypeOf(a, c, d, b) == [*:0]allowzero align(2) const volatile u8); + comptime assert(@TypeOf(a, d, b, c) == [*:0]allowzero align(2) const volatile u8); + comptime assert(@TypeOf(a, d, c, b) == [*:0]allowzero align(2) const volatile u8); + + comptime assert(@TypeOf(b, a, c, d) == [*:0]allowzero align(2) const volatile u8); + comptime assert(@TypeOf(b, a, d, c) == [*:0]allowzero align(2) const volatile u8); + comptime assert(@TypeOf(b, c, a, d) == [*:0]allowzero align(2) const volatile u8); + comptime assert(@TypeOf(b, c, d, a) == [*:0]allowzero align(2) const volatile u8); + comptime assert(@TypeOf(b, d, c, a) == [*:0]allowzero align(2) const volatile u8); + comptime assert(@TypeOf(b, d, a, c) == [*:0]allowzero align(2) const volatile u8); + + comptime assert(@TypeOf(c, a, b, d) == [*:0]allowzero align(2) const volatile u8); + comptime assert(@TypeOf(c, a, d, b) == [*:0]allowzero align(2) const volatile u8); + comptime assert(@TypeOf(c, b, a, d) == [*:0]allowzero align(2) const volatile u8); + comptime assert(@TypeOf(c, b, d, a) == [*:0]allowzero align(2) const volatile u8); + comptime assert(@TypeOf(c, d, b, a) == [*:0]allowzero align(2) const volatile u8); + comptime assert(@TypeOf(c, d, a, b) == [*:0]allowzero align(2) const volatile u8); + + comptime assert(@TypeOf(d, a, b, c) == [*:0]allowzero align(2) const volatile u8); + comptime assert(@TypeOf(d, a, c, b) == [*:0]allowzero align(2) const volatile u8); + comptime assert(@TypeOf(d, b, a, c) == [*:0]allowzero align(2) const volatile u8); + comptime assert(@TypeOf(d, b, c, a) == [*:0]allowzero align(2) const volatile u8); + comptime assert(@TypeOf(d, c, b, a) == [*:0]allowzero align(2) const volatile u8); + comptime assert(@TypeOf(d, c, a, b) == [*:0]allowzero align(2) const volatile u8); var x: u8 = 0; _ = &x; const r1 = switch (x) { 0 => a, 1 => b, - else => c, + 2 => c, + else => d, }; const r2 = switch (x) { 0 => b, 1 => a, - else => c, + 2 => c, + else => d, }; const r3 = switch (x) { 0 => c, 1 => a, - else => b, + 2 => b, + else => d, + }; + const r4 = switch (x) { + 0 => d, + 1 => a, + 2 => b, + else => c, }; - try expectEqualSlices(u8, std.mem.span(@volatileCast(r1)), "foo"); - try expectEqualSlices(u8, std.mem.span(@volatileCast(r2)), "bar"); - try expectEqualSlices(u8, std.mem.span(@volatileCast(r3)), "baz"); + const NonAllowZero = comptime blk: { + var ti = @typeInfo(@TypeOf(r1, r2, r3, r4)); + ti.pointer.is_allowzero = false; + break :blk @Type(ti); + }; + try expectEqualSlices(u8, std.mem.span(@volatileCast(@as(NonAllowZero, @ptrCast(r1)))), "foo"); + try expectEqualSlices(u8, std.mem.span(@volatileCast(@as(NonAllowZero, @ptrCast(r2)))), "bar"); + try expectEqualSlices(u8, std.mem.span(@volatileCast(@as(NonAllowZero, @ptrCast(r3)))), "baz"); + try expectEqualSlices(u8, std.mem.span(@volatileCast(@as(NonAllowZero, @ptrCast(r4)))), "qux"); } test "peer type resolution: arrays of compatible types" {