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...@@ -2136,10 +2136,12 @@ fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType
2136 // here while looking for modifiers as that could result in false2136 // here while looking for modifiers as that could result in false
2137 // positives. Therefore, start after a sentinel if there is one and2137 // positives. Therefore, start after a sentinel if there is one and
2138 // skip over any align node and bit range nodes.2138 // skip over any align node and bit range nodes.
2139 var i = if (info.sentinel.unwrap()) |sentinel| tree.lastToken(sentinel) + 1 else switch (size) {2139 var i = (if (info.sentinel.unwrap()) |sentinel| tree.lastToken(sentinel) + 1 else switch (size) {
2140 .many, .c => info.main_token + 1,2140 .one => info.main_token,
2141 else => info.main_token,2141 .slice => info.main_token + 1,
2142 };2142 .many => info.main_token + 2,
2143 .c => info.main_token + 3,
2144 }) + 1;
2143 const end = tree.firstToken(info.child_type);2145 const end = tree.firstToken(info.child_type);
2144 while (i < end) : (i += 1) {2146 while (i < end) : (i += 1) {
2145 switch (tree.tokenTag(i)) {2147 switch (tree.tokenTag(i)) {
...@@ -2147,15 +2149,15 @@ fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType...@@ -2147,15 +2149,15 @@ fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType
2147 .keyword_const => result.const_token = i,2149 .keyword_const => result.const_token = i,
2148 .keyword_volatile => result.volatile_token = i,2150 .keyword_volatile => result.volatile_token = i,
2149 .keyword_align => {2151 .keyword_align => {
2150 const align_node = info.align_node.unwrap().?;
2151 if (info.bit_range_end.unwrap()) |bit_range_end| {2152 if (info.bit_range_end.unwrap()) |bit_range_end| {
2152 assert(info.bit_range_start != .none);2153 assert(info.bit_range_start != .none);
2153 i = tree.lastToken(bit_range_end) + 1;2154 i = tree.lastToken(bit_range_end) + 1;
2154 } else {2155 } else if (info.align_node.unwrap()) |align_node| {
2155 i = tree.lastToken(align_node) + 1;2156 i = tree.lastToken(align_node) + 1;
2156 }2157 } else unreachable;
2157 },2158 },
2158 else => {},2159 .keyword_addrspace => i = tree.lastToken(info.addrspace_node.unwrap().?) + 1,
2160 else => unreachable,
2159 }2161 }
2160 }2162 }
2161 return result;2163 return result;
lib/std/zig/parser_test.zig+17
...@@ -6973,6 +6973,23 @@ test "ampersand" {...@@ -6973,6 +6973,23 @@ test "ampersand" {
6973 , &.{});6973 , &.{});
6974}6974}
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
6976var fixed_buffer_mem: [100 * 1024]u8 = undefined;6993var fixed_buffer_mem: [100 * 1024]u8 = undefined;
69776994
6978fn testParse(io: Io, source: [:0]const u8, allocator: Allocator, anything_changed: *bool) ![]u8 {6995fn testParse(io: Io, source: [:0]const u8, allocator: Allocator, anything_changed: *bool) ![]u8 {