From f2328d520860049f542539e4e28c401970870f84 Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Tue, 7 Jul 2026 10:43:12 +0200 Subject: [PATCH] grammar: fix addrspace/align pointer modifiers Currently the grammar doesn't function as intended and forbids addrspace followed by align. Add the required negative lookaheads to fix this as well as a test case. --- doc/langref/grammar.peg | 8 ++++---- lib/std/zig/parser_fuzz.zig | 8 ++++++++ lib/std/zig/parser_generated_oracle.zig | 20 ++++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/doc/langref/grammar.peg b/doc/langref/grammar.peg index 3b88469e4d90cc2ada0bc96e348d3b03a59d80e9..17c25427dc8f3a4b438f11d8fc5e923540b06c74 100644 --- a/doc/langref/grammar.peg +++ b/doc/langref/grammar.peg @@ -376,12 +376,12 @@ PrefixTypeOp # while permitting arbitrary order. A compile error for duplicates single-token modifiers # is emitted during "AstGen" after parsing is complete. PtrMods - <- PtrMod* ByteAlign? PtrMod* AddrSpace? PtrMod* - / PtrMod* AddrSpace? PtrMod* ByteAlign? PtrMod* + <- PtrMod* !KEYWORD_addrspace ByteAlign? PtrMod* AddrSpace? PtrMod* + / PtrMod* !KEYWORD_align AddrSpace? PtrMod* ByteAlign? PtrMod* SinglePtrMods - <- PtrMod* BitAlign? PtrMod* AddrSpace? PtrMod* - / PtrMod* AddrSpace? PtrMod* BitAlign? PtrMod* + <- PtrMod* !KEYWORD_addrspace BitAlign? PtrMod* AddrSpace? PtrMod* + / PtrMod* !KEYWORD_align AddrSpace? PtrMod* BitAlign? PtrMod* PtrMod <- KEYWORD_allowzero diff --git a/lib/std/zig/parser_fuzz.zig b/lib/std/zig/parser_fuzz.zig index b2ae33b8029edd2ed0802e01725da43193a0648c..7cbf4f895c1c940dfceaa0b1e8a93df5c1e9db74 100644 --- a/lib/std/zig/parser_fuzz.zig +++ b/lib/std/zig/parser_fuzz.zig @@ -114,6 +114,14 @@ test "volatile const" { try checkAgainstOracle("*volatile\nconst\n0"); } +// Found using AFL++ +test "addrspace align" { + try checkAgainstOracle("*addrspace(0) align(0) 0"); + try checkAgainstOracle("*align(0) addrspace(0) 0"); + try checkAgainstOracle("[*]addrspace(0) align(0) 0"); + try checkAgainstOracle("[*]align(0) addrspace(0) 0"); +} + // Found using AFL++ test "catch capture whitespace" { try checkAgainstOracle("test{0 catch |h|0;}"); diff --git a/lib/std/zig/parser_generated_oracle.zig b/lib/std/zig/parser_generated_oracle.zig index 0000d9c4eaa2da30f3f75d5f78247955a7d1bef6..15252098a1839c445e16c05db6a3ff144e1b5668 100644 --- a/lib/std/zig/parser_generated_oracle.zig +++ b/lib/std/zig/parser_generated_oracle.zig @@ -1876,6 +1876,11 @@ const Parser = struct { i_1 += 1; } break :blk_1 true; + } and blk_1: { + const pos_1 = p.i; + const match_1 = try p.parseKEYWORD_addrspace(); + p.i = pos_1; + break :blk_1 !match_1; } and (try p.parseByteAlign() or true) and blk_1: { var i_1: usize = 0; while (try p.parsePtrMod()) { @@ -1899,6 +1904,11 @@ const Parser = struct { i_1 += 1; } break :blk_1 true; + } and blk_1: { + const pos_1 = p.i; + const match_1 = try p.parseKEYWORD_align(); + p.i = pos_1; + break :blk_1 !match_1; } and (try p.parseAddrSpace() or true) and blk_1: { var i_1: usize = 0; while (try p.parsePtrMod()) { @@ -1928,6 +1938,11 @@ const Parser = struct { i_1 += 1; } break :blk_1 true; + } and blk_1: { + const pos_1 = p.i; + const match_1 = try p.parseKEYWORD_addrspace(); + p.i = pos_1; + break :blk_1 !match_1; } and (try p.parseBitAlign() or true) and blk_1: { var i_1: usize = 0; while (try p.parsePtrMod()) { @@ -1951,6 +1966,11 @@ const Parser = struct { i_1 += 1; } break :blk_1 true; + } and blk_1: { + const pos_1 = p.i; + const match_1 = try p.parseKEYWORD_align(); + p.i = pos_1; + break :blk_1 !match_1; } and (try p.parseAddrSpace() or true) and blk_1: { var i_1: usize = 0; while (try p.parsePtrMod()) { -- 2.54.0