Ast: fix pointer types with subexprs containing qualifiers

This commit is contained in:
Kendall Condon 2025-07-28 14:01:55 -04:00
parent ed8b85d95d
commit c9acfe4c2b
2 changed files with 27 additions and 8 deletions

View file

@ -2143,10 +2143,12 @@ fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType
// here while looking for modifiers as that could result in false
// positives. Therefore, start after a sentinel if there is one and
// skip over any align node and bit range nodes.
var i = if (info.sentinel.unwrap()) |sentinel| tree.lastToken(sentinel) + 1 else switch (size) {
.many, .c => info.main_token + 1,
else => info.main_token,
};
var i = (if (info.sentinel.unwrap()) |sentinel| tree.lastToken(sentinel) + 1 else switch (size) {
.one => info.main_token,
.slice => info.main_token + 1,
.many => info.main_token + 2,
.c => info.main_token + 3,
}) + 1;
const end = tree.firstToken(info.child_type);
while (i < end) : (i += 1) {
switch (tree.tokenTag(i)) {
@ -2154,15 +2156,15 @@ fn fullPtrTypeComponents(tree: Ast, info: full.PtrType.Components) full.PtrType
.keyword_const => result.const_token = i,
.keyword_volatile => result.volatile_token = i,
.keyword_align => {
const align_node = info.align_node.unwrap().?;
if (info.bit_range_end.unwrap()) |bit_range_end| {
assert(info.bit_range_start != .none);
i = tree.lastToken(bit_range_end) + 1;
} else {
} else if (info.align_node.unwrap()) |align_node| {
i = tree.lastToken(align_node) + 1;
}
} else unreachable;
},
else => {},
.keyword_addrspace => i = tree.lastToken(info.addrspace_node.unwrap().?) + 1,
else => unreachable,
}
}
return result;

View file

@ -7039,6 +7039,23 @@ test "ampersand" {
, &.{});
}
test "Ast: pointer types with subexprs containing qualifiers" {
var fixed_allocator = std.heap.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
const allocator = fixed_allocator.allocator();
var tree = try std.zig.Ast.parse(allocator, "**addrspace(*align(1)T)T", .zon);
defer tree.deinit(allocator);
const regular_ptr_node = tree.nodeData(.root).node;
const full_regular_ptr = tree.fullPtrType(regular_ptr_node) orelse return error.TestFailed;
try std.testing.expect(full_regular_ptr.ast.addrspace_node == .none);
try std.testing.expect(full_regular_ptr.ast.align_node == .none);
const special_ptr_node = full_regular_ptr.ast.child_type;
const full_special_ptr = tree.fullPtrType(special_ptr_node) orelse return error.TestFailed;
try std.testing.expect(full_special_ptr.ast.addrspace_node != .none);
try std.testing.expect(full_special_ptr.ast.align_node == .none);
}
var fixed_buffer_mem: [100 * 1024]u8 = undefined;
fn testParse(source: [:0]const u8, allocator: mem.Allocator, anything_changed: *bool) ![]u8 {