authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2026-07-07 10:43:12+02:00
committergravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2026-07-08 11:49:02+02:00
logf2328d520860049f542539e4e28c401970870f84
tree88ba4fba603b98b68915380c56bef221d49f3766
parente6749167feb6841b3a81abb3863025d74dae9b7d
signaturelock-open Commit is signed but in an unrecognized format.

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.

3 files changed, 32 insertions(+), 4 deletions(-)

doc/langref/grammar.peg+4-4
......@@ -376,12 +376,12 @@ PrefixTypeOp
376376# while permitting arbitrary order. A compile error for duplicates single-token modifiers
377377# is emitted during "AstGen" after parsing is complete.
378378PtrMods
379 <- PtrMod* ByteAlign? PtrMod* AddrSpace? PtrMod*
380 / PtrMod* AddrSpace? PtrMod* ByteAlign? PtrMod*
379 <- PtrMod* !KEYWORD_addrspace ByteAlign? PtrMod* AddrSpace? PtrMod*
380 / PtrMod* !KEYWORD_align AddrSpace? PtrMod* ByteAlign? PtrMod*
381381
382382SinglePtrMods
383 <- PtrMod* BitAlign? PtrMod* AddrSpace? PtrMod*
384 / PtrMod* AddrSpace? PtrMod* BitAlign? PtrMod*
383 <- PtrMod* !KEYWORD_addrspace BitAlign? PtrMod* AddrSpace? PtrMod*
384 / PtrMod* !KEYWORD_align AddrSpace? PtrMod* BitAlign? PtrMod*
385385
386386PtrMod
387387 <- KEYWORD_allowzero
lib/std/zig/parser_fuzz.zig+8
......@@ -114,6 +114,14 @@ test "volatile const" {
114114 try checkAgainstOracle("*volatile\nconst\n0");
115115}
116116
117// Found using AFL++
118test "addrspace align" {
119 try checkAgainstOracle("*addrspace(0) align(0) 0");
120 try checkAgainstOracle("*align(0) addrspace(0) 0");
121 try checkAgainstOracle("[*]addrspace(0) align(0) 0");
122 try checkAgainstOracle("[*]align(0) addrspace(0) 0");
123}
124
117125// Found using AFL++
118126test "catch capture whitespace" {
119127 try checkAgainstOracle("test{0 catch |h|0;}");
lib/std/zig/parser_generated_oracle.zig+20
......@@ -1876,6 +1876,11 @@ const Parser = struct {
18761876 i_1 += 1;
18771877 }
18781878 break :blk_1 true;
1879 } and blk_1: {
1880 const pos_1 = p.i;
1881 const match_1 = try p.parseKEYWORD_addrspace();
1882 p.i = pos_1;
1883 break :blk_1 !match_1;
18791884 } and (try p.parseByteAlign() or true) and blk_1: {
18801885 var i_1: usize = 0;
18811886 while (try p.parsePtrMod()) {
......@@ -1899,6 +1904,11 @@ const Parser = struct {
18991904 i_1 += 1;
19001905 }
19011906 break :blk_1 true;
1907 } and blk_1: {
1908 const pos_1 = p.i;
1909 const match_1 = try p.parseKEYWORD_align();
1910 p.i = pos_1;
1911 break :blk_1 !match_1;
19021912 } and (try p.parseAddrSpace() or true) and blk_1: {
19031913 var i_1: usize = 0;
19041914 while (try p.parsePtrMod()) {
......@@ -1928,6 +1938,11 @@ const Parser = struct {
19281938 i_1 += 1;
19291939 }
19301940 break :blk_1 true;
1941 } and blk_1: {
1942 const pos_1 = p.i;
1943 const match_1 = try p.parseKEYWORD_addrspace();
1944 p.i = pos_1;
1945 break :blk_1 !match_1;
19311946 } and (try p.parseBitAlign() or true) and blk_1: {
19321947 var i_1: usize = 0;
19331948 while (try p.parsePtrMod()) {
......@@ -1951,6 +1966,11 @@ const Parser = struct {
19511966 i_1 += 1;
19521967 }
19531968 break :blk_1 true;
1969 } and blk_1: {
1970 const pos_1 = p.i;
1971 const match_1 = try p.parseKEYWORD_align();
1972 p.i = pos_1;
1973 break :blk_1 !match_1;
19541974 } and (try p.parseAddrSpace() or true) and blk_1: {
19551975 var i_1: usize = 0;
19561976 while (try p.parsePtrMod()) {