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...@@ -376,12 +376,12 @@ PrefixTypeOp
376# while permitting arbitrary order. A compile error for duplicates single-token modifiers376# while permitting arbitrary order. A compile error for duplicates single-token modifiers
377# is emitted during "AstGen" after parsing is complete.377# is emitted during "AstGen" after parsing is complete.
378PtrMods378PtrMods
379 <- PtrMod* ByteAlign? PtrMod* AddrSpace? PtrMod*379 <- PtrMod* !KEYWORD_addrspace ByteAlign? PtrMod* AddrSpace? PtrMod*
380 / PtrMod* AddrSpace? PtrMod* ByteAlign? PtrMod*380 / PtrMod* !KEYWORD_align AddrSpace? PtrMod* ByteAlign? PtrMod*
381381
382SinglePtrMods382SinglePtrMods
383 <- PtrMod* BitAlign? PtrMod* AddrSpace? PtrMod*383 <- PtrMod* !KEYWORD_addrspace BitAlign? PtrMod* AddrSpace? PtrMod*
384 / PtrMod* AddrSpace? PtrMod* BitAlign? PtrMod*384 / PtrMod* !KEYWORD_align AddrSpace? PtrMod* BitAlign? PtrMod*
385385
386PtrMod386PtrMod
387 <- KEYWORD_allowzero387 <- KEYWORD_allowzero
lib/std/zig/parser_fuzz.zig+8
...@@ -114,6 +114,14 @@ test "volatile const" {...@@ -114,6 +114,14 @@ test "volatile const" {
114 try checkAgainstOracle("*volatile\nconst\n0");114 try checkAgainstOracle("*volatile\nconst\n0");
115}115}
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
117// Found using AFL++125// Found using AFL++
118test "catch capture whitespace" {126test "catch capture whitespace" {
119 try checkAgainstOracle("test{0 catch |h|0;}");127 try checkAgainstOracle("test{0 catch |h|0;}");
lib/std/zig/parser_generated_oracle.zig+20
...@@ -1876,6 +1876,11 @@ const Parser = struct {...@@ -1876,6 +1876,11 @@ const Parser = struct {
1876 i_1 += 1;1876 i_1 += 1;
1877 }1877 }
1878 break :blk_1 true;1878 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;
1879 } and (try p.parseByteAlign() or true) and blk_1: {1884 } and (try p.parseByteAlign() or true) and blk_1: {
1880 var i_1: usize = 0;1885 var i_1: usize = 0;
1881 while (try p.parsePtrMod()) {1886 while (try p.parsePtrMod()) {
...@@ -1899,6 +1904,11 @@ const Parser = struct {...@@ -1899,6 +1904,11 @@ const Parser = struct {
1899 i_1 += 1;1904 i_1 += 1;
1900 }1905 }
1901 break :blk_1 true;1906 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;
1902 } and (try p.parseAddrSpace() or true) and blk_1: {1912 } and (try p.parseAddrSpace() or true) and blk_1: {
1903 var i_1: usize = 0;1913 var i_1: usize = 0;
1904 while (try p.parsePtrMod()) {1914 while (try p.parsePtrMod()) {
...@@ -1928,6 +1938,11 @@ const Parser = struct {...@@ -1928,6 +1938,11 @@ const Parser = struct {
1928 i_1 += 1;1938 i_1 += 1;
1929 }1939 }
1930 break :blk_1 true;1940 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;
1931 } and (try p.parseBitAlign() or true) and blk_1: {1946 } and (try p.parseBitAlign() or true) and blk_1: {
1932 var i_1: usize = 0;1947 var i_1: usize = 0;
1933 while (try p.parsePtrMod()) {1948 while (try p.parsePtrMod()) {
...@@ -1951,6 +1966,11 @@ const Parser = struct {...@@ -1951,6 +1966,11 @@ const Parser = struct {
1951 i_1 += 1;1966 i_1 += 1;
1952 }1967 }
1953 break :blk_1 true;1968 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;
1954 } and (try p.parseAddrSpace() or true) and blk_1: {1974 } and (try p.parseAddrSpace() or true) and blk_1: {
1955 var i_1: usize = 0;1975 var i_1: usize = 0;
1956 while (try p.parsePtrMod()) {1976 while (try p.parsePtrMod()) {