authorgravatar for goon.pri.low@gmail.comKendall Condon <goon.pri.low@gmail.com> 2025-07-28 14:01:55-04:00
committergravatar for goon.pri.low@gmail.comKendall Condon <goon.pri.low@gmail.com> 2026-03-12 17:23:22-04:00
log84ac2e8714735ceeefad840e41961f6407e0c619
treef823366bd2f5b583573a7a360f85bbd93e61503c
parente03851e522738b6ed2259e742e5f2e2f4676ef75

Ast: fix pointer types with subexprs containing qualifiers


2 files changed, 27 insertions(+), 8 deletions(-)

lib/std/zig/Ast.zig+10-8
......@@ -2136,10 +2136,12 @@ fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType
21362136 // here while looking for modifiers as that could result in false
21372137 // positives. Therefore, start after a sentinel if there is one and
21382138 // skip over any align node and bit range nodes.
2139 var i = if (info.sentinel.unwrap()) |sentinel| tree.lastToken(sentinel) + 1 else switch (size) {
2140 .many, .c => info.main_token + 1,
2141 else => info.main_token,
2142 };
2139 var i = (if (info.sentinel.unwrap()) |sentinel| tree.lastToken(sentinel) + 1 else switch (size) {
2140 .one => info.main_token,
2141 .slice => info.main_token + 1,
2142 .many => info.main_token + 2,
2143 .c => info.main_token + 3,
2144 }) + 1;
21432145 const end = tree.firstToken(info.child_type);
21442146 while (i < end) : (i += 1) {
21452147 switch (tree.tokenTag(i)) {
......@@ -2147,15 +2149,15 @@ fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType
21472149 .keyword_const => result.const_token = i,
21482150 .keyword_volatile => result.volatile_token = i,
21492151 .keyword_align => {
2150 const align_node = info.align_node.unwrap().?;
21512152 if (info.bit_range_end.unwrap()) |bit_range_end| {
21522153 assert(info.bit_range_start != .none);
21532154 i = tree.lastToken(bit_range_end) + 1;
2154 } else {
2155 } else if (info.align_node.unwrap()) |align_node| {
21552156 i = tree.lastToken(align_node) + 1;
2156 }
2157 } else unreachable;
21572158 },
2158 else => {},
2159 .keyword_addrspace => i = tree.lastToken(info.addrspace_node.unwrap().?) + 1,
2160 else => unreachable,
21592161 }
21602162 }
21612163 return result;
lib/std/zig/parser_test.zig+17
......@@ -6973,6 +6973,23 @@ test "ampersand" {
69736973 , &.{});
69746974}
69756975
6976test "Ast: pointer types with subexprs containing qualifiers" {
6977 var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
6978 const allocator = fixed_allocator.allocator();
6979 var tree = try std.zig.Ast.parse(allocator, "**addrspace(*align(1)T)T", .zon);
6980 defer tree.deinit(allocator);
6981
6982 const regular_ptr_node = tree.nodeData(.root).node;
6983 const full_regular_ptr = tree.fullPtrType(regular_ptr_node) orelse return error.TestFailed;
6984 try std.testing.expect(full_regular_ptr.ast.addrspace_node == .none);
6985 try std.testing.expect(full_regular_ptr.ast.align_node == .none);
6986
6987 const special_ptr_node = full_regular_ptr.ast.child_type;
6988 const full_special_ptr = tree.fullPtrType(special_ptr_node) orelse return error.TestFailed;
6989 try std.testing.expect(full_special_ptr.ast.addrspace_node != .none);
6990 try std.testing.expect(full_special_ptr.ast.align_node == .none);
6991}
6992
69766993var fixed_buffer_mem: [100 * 1024]u8 = undefined;
69776994
69786995fn testParse(io: Io, source: [:0]const u8, allocator: Allocator, anything_changed: *bool) ![]u8 {