ziglang/zig
262
5.9k
Fork
You've already forked zig
759

add an ast smith #31635

Merged
andrewrk merged 11 commits from gooncreeper/zig:ast-smith into master 2026年04月02日 15:41:10 +02:00
Contributor
Copy link

Supersedes https://github.com/ziglang/zig/pull/24487

AstSmith

This generates zig ASTs from testing.Smith and is based off the langref's PEG.

The choice to not build the Ast while generating and instead parsing it afterwards makes the smith more versatile by not being tied to a single implementation at a cost of efficiency.

Additionally, a new function boolWeighted was added to Smith due to its frequent use in AstSmith.

PEG / Parser Changes

All the changes made here are to places where the PEG was more permissive than the parser. Changes to the parser make it more permissive and changes to the PEG make it more strict. When choosing between these two options for discrepancies, I opted for the choice that was more natural and increased code readability.

Changes to the Parser

  • Tuple types can now be inline and extern (e.g. extern struct).
  • Break labels are now only consumed if both the colon and identifier are present instead of failing if there is only a colon.
  • Labeled blocks are no longer parsed in PrimaryExpr (so they are now allowed to have CurlySuffixExpr) as in the PEG.
  • While expressions can now be grouped on the same line.
  • Added distinction in error messages for "a multiline string literal" so places where only single string literals are allowed do not give "expected 'a string literal', found 'a string literal'".

Changes to the PEG

  • Made it so extern functions cannot have a body
  • Made it so ... can be only the last function argument
  • Made it so many item pointers can't have bit alignment
  • Made it so asm inputs / outputs can not be multiline string literals
  • Added distinction between block-level statements and regular statements

Pointer Qualifier Order

The PEG allowed for duplicated qualifiers, which the parser did not. The simplest fix for this was to make each be allowed zero or one times which required giving them a order similar to how FnProto already works. The chosen order is the same as used by zig fmt. The parser still accepts them in any order similar to functions.

Backtracking

Made it so several places could not backtrack in the PEG. A common pattern for this was (A / !A).

!ExprSuffix

Expressions ending with expressions now have !ExprSuffix after. This change prevents expressions such as if (a) T else U{} being be parsable as (if (a) T else U){}. It also stops some backtracking, take for example:

if (a) for (b) |c| d else |e| f

It may seem at first that the else clause belongs to the for, however
it actually belongs to the if because for else-clauses cannot have a
payload. This is fixed by a new KEYWORD_else / !KEYWORD_else, however
this alone does not fix more complex cases such as:

if (a) for (b) |c| d() else |e| f

The PEG would first attempt to parse it as expected but fail due to the new guard. It will then backtrack to

if (a) (for (b) |c| d)() else |e| f

which is surprising but avoids the new guard. So, !ExprSuffix is required to disallow this type of backtracking.

!LabelableExpr

For identifiers, excluding labels is necessary despite ordered choice due to pointer bit alignment. For example *align(a : b: for (c) e) T could backtrack to *align(a : b : (for (c) e)) T.

!SinglePtrTypeStart

Prevents expressions like break * break which is parsed as break (*break) backtracking to (break) * (break)

!BlockExpr

Prevents expressions like test { {} = a; } being backtracked to and parsed as test { ({} = a); } (the parenthesis are just for demonstration, that expression is not legal either)

!ExprStatement

In addition to splitting up block level statements, statements that are also parsable as expressions are now part of ExprStatement to disallow backtracking.

zig fmt

The fuzz test for zig fmt has been updated to use AstSmith and has found several new bugs which have been fixed.

Supersedes https://github.com/ziglang/zig/pull/24487 # AstSmith This generates zig ASTs from `testing.Smith` and is based off the langref's PEG. The choice to not build the Ast while generating and instead parsing it afterwards makes the smith more versatile by not being tied to a single implementation at a cost of efficiency. Additionally, a new function `boolWeighted` was added to `Smith` due to its frequent use in `AstSmith`. # PEG / Parser Changes All the changes made here are to places where the PEG was more permissive than the parser. Changes to the parser make it more permissive and changes to the PEG make it more strict. When choosing between these two options for discrepancies, I opted for the choice that was more natural and increased code readability. Changes to the Parser * Tuple types can now be `inline` and `extern` (e.g. `extern struct`). * Break labels are now only consumed if both the colon and identifier are present instead of failing if there is only a colon. * Labeled blocks are no longer parsed in PrimaryExpr (so they are now allowed to have CurlySuffixExpr) as in the PEG. * While expressions can now be grouped on the same line. * Added distinction in error messages for "a multiline string literal" so places where only single string literals are allowed do not give "expected 'a string literal', found 'a string literal'". Changes to the PEG * Made it so extern functions cannot have a body * Made it so ... can be only the last function argument * Made it so many item pointers can't have bit alignment * Made it so asm inputs / outputs can not be multiline string literals * Added distinction between block-level statements and regular statements ## Pointer Qualifier Order The PEG allowed for duplicated qualifiers, which the parser did not. The simplest fix for this was to make each be allowed zero or one times which required giving them a order similar to how FnProto already works. The chosen order is the same as used by zig fmt. The parser still accepts them in any order similar to functions. ## Backtracking Made it so several places could not backtrack in the PEG. A common pattern for this was (A / !A). ### !ExprSuffix Expressions ending with expressions now have !ExprSuffix after. This change prevents expressions such as `if (a) T else U{}` being be parsable as `(if (a) T else U){}`. It also stops some backtracking, take for example: `if (a) for (b) |c| d else |e| f` It may seem at first that the else clause belongs to the `for`, however it actually belongs to the `if` because for else-clauses cannot have a payload. This is fixed by a new `KEYWORD_else / !KEYWORD_else`, however this alone does not fix more complex cases such as: `if (a) for (b) |c| d() else |e| f` The PEG would first attempt to parse it as expected but fail due to the new guard. It will then backtrack to `if (a) (for (b) |c| d)() else |e| f` which is surprising but avoids the new guard. So, !ExprSuffix is required to disallow this type of backtracking. ### !LabelableExpr For identifiers, excluding labels is necessary despite ordered choice due to pointer bit alignment. For example `*align(a : b: for (c) e) T` could backtrack to `*align(a : b : (for (c) e)) T`. ### !SinglePtrTypeStart Prevents expressions like `break * break` which is parsed as `break (*break)` backtracking to `(break) * (break)` ### !BlockExpr Prevents expressions like `test { {} = a; }` being backtracked to and parsed as `test { ({} = a); }` (the parenthesis are just for demonstration, that expression is not legal either) ### !ExprStatement In addition to splitting up block level statements, statements that are also parsable as expressions are now part of ExprStatement to disallow backtracking. # zig fmt The fuzz test for zig fmt has been updated to use AstSmith and has found several new bugs which have been fixed.
Contributor
Copy link

Tuple types can now be inline and extern (e.g. extern struct).

as in inline struct..?
extern was intentionally disallowed in https://github.com/ziglang/zig/pull/16551, might need some justification to reallow it

> Tuple types can now be inline and extern (e.g. extern struct). as in `inline struct`..? extern was intentionally disallowed in https://github.com/ziglang/zig/pull/16551, might need some justification to reallow it
Author
Contributor
Copy link

@pentuppup wrote in #31635 (comment):

Tuple types can now be inline and extern (e.g. extern struct).

as in inline struct..? extern was intentionally disallowed in https://github.com/ziglang/zig/pull/16551, might need some justification to reallow it

Apologies if that was misleading, I mean as in the tuple fields starting with inline or extern. For example, const T = struct { u32, packed struct { a: u64, b: u64 }, inline for (a) b };.

@pentuppup wrote in https://codeberg.org/ziglang/zig/pulls/31635#issuecomment-12007050: > > Tuple types can now be inline and extern (e.g. extern struct). > > as in `inline struct`..? extern was intentionally disallowed in https://github.com/ziglang/zig/pull/16551, might need some justification to reallow it Apologies if that was misleading, I mean as in the tuple fields starting with inline or extern. For example, `const T = struct { u32, packed struct { a: u64, b: u64 }, inline for (a) b };`.
@ -0,0 +2408,4 @@
.value(Kind,.copy_identifier,6),
};
constn_weights=@as(usize,2)+@intFromBool(a.prev_ids_len!=0);
constkind=a.smith.valueWeighted(Kind,kind_weights[0..n_weights]);
Contributor
Copy link

With some meta programming, you can also do something like:

const kind = a.smith.enumWeighted(Kind, .{
 .underscore = 6, 
 .regular_identifier = 3, 
 .quoted_identifier = 1, 
 .copy_identifier = 6, 
})

or maybe even

const kind = a.smith.autoEnumWeighted(.{
 .underscore = 6, 
 .regular_identifier = 3, 
 .quoted_identifier = 1, 
 .copy_identifier = 6, 
})

This is slightly more concise syntactically, and comptime-checks that enum is synced with weights.

We use this pattern fairly frequently at TigerBeetle.

With some meta programming, you can also do something like: ``` const kind = a.smith.enumWeighted(Kind, .{ .underscore = 6, .regular_identifier = 3, .quoted_identifier = 1, .copy_identifier = 6, }) ``` or maybe even ``` const kind = a.smith.autoEnumWeighted(.{ .underscore = 6, .regular_identifier = 3, .quoted_identifier = 1, .copy_identifier = 6, }) ``` This is slightly more concise syntactically, and comptime-checks that enum is synced with weights. We use this pattern fairly frequently at TigerBeetle.
Author
Contributor
Copy link

In this scenario such function would not be applicable as copy_identifier is being dynamically included in the weights (via slicing them). Adding such a function also impedes defining weights via ranges which is more efficient (and concise); currently there is nowhere else in AstSmith which this would be applicable. So, I do not believe such a function is yet justified.

In this scenario such function would not be applicable as `copy_identifier` is being dynamically included in the weights (via slicing them). Adding such a function also impedes defining weights via ranges which is more efficient (and concise); currently there is nowhere else in AstSmith which this would be applicable. So, I do not believe such a function is yet justified.
Contributor
Copy link

I think it's still works with dynamic weights, and it seems that

const kind = a.smith.autoEnumWeighted(.{
 .underscore = 6, 
 .regular_identifier = 3, 
 .quoted_identifier = 1, 
 .copy_identifier = if (a.prev_ids_len == 0) 0 else 6, 
})

is a touch more direct way to express optionality than weight slicing. I do like the weights construct though, its' very general!

Actually, isn't the code buggy at present?

 const kind_weights: [4]Weight = .{
 .value(Kind, .underscore, 6),
 .value(Kind, .regular_identifier, 3),
 .value(Kind, .quoted_identifier, 1),
 .value(Kind, .copy_identifier, 6),
 };
 const n_weights = @as(usize, 2) + @intFromBool(a.prev_ids_len != 0);

It should be @as(usize, 3), not 2, right?

(NB: here and elsewhere, I intend only to point out what's possible, you of course have more context what works best in context of smith.zig!)

I think it's still works with dynamic weights, and it seems that ``` const kind = a.smith.autoEnumWeighted(.{ .underscore = 6, .regular_identifier = 3, .quoted_identifier = 1, .copy_identifier = if (a.prev_ids_len == 0) 0 else 6, }) ``` is a touch more direct way to express optionality than weight slicing. I do like the weights construct though, its' very general! Actually, isn't the code buggy at present? ``` const kind_weights: [4]Weight = .{ .value(Kind, .underscore, 6), .value(Kind, .regular_identifier, 3), .value(Kind, .quoted_identifier, 1), .value(Kind, .copy_identifier, 6), }; const n_weights = @as(usize, 2) + @intFromBool(a.prev_ids_len != 0); ``` It should be `@as(usize, 3)`, not `2`, right? (NB: here and elsewhere, I intend only to point out what's possible, you of course have more context what works best in context of smith.zig!)
Author
Contributor
Copy link

Good catch!

Regarding that approach for dynamic weights, it would require extra logic in enumWeighted since weights of zero are disallowed to simplify checking if a value is in a set of weights. This is also another reason to keep the logic in the callee who can then construct the weights more efficiently.

Good catch! Regarding that approach for dynamic weights, it would require extra logic in enumWeighted since weights of zero are disallowed to simplify checking if a value is in a set of weights. This is also another reason to keep the logic in the callee who can then construct the weights more efficiently.
@ -0,0 +2458,4 @@
fnpegBuiltinIdentifier(a:*AstSmith)SourceError!void{
trya.addTokenTag(.builtin);
if(a.smith.boolWeighted(1,31)){
if(a.smith.boolWeighted(1,8)){
Contributor
Copy link

For TigerBeetle, we ended up introducing a Ratio type to specify the weights, so the equivalent call would be a.smith.boolWeighted(ratio(1, 8)). The reason for that is that it makes easier to make Ratio a parameter:

a.smith.boolWeighted(a.options.ptrCastChance);

And that is useful because it enables swarm testing --- you can generate ptrCastChance itself from fuzzer input once at the start of the test. So, instead of all examples having the same average ratio of pointer casts, you can get examples which are mostly pointer casts, and examples which are hardly ever pointer casts. And SWARM testing literature (and common sense) tells that the latter is potentially more interesting.

For TigerBeetle, we ended up introducing a `Ratio` type to specify the weights, so the equivalent call would be `a.smith.boolWeighted(ratio(1, 8))`. The reason for that is that it makes easier to make `Ratio` a parameter: ``` a.smith.boolWeighted(a.options.ptrCastChance); ``` And _that_ is useful because it enables swarm testing --- you can generate `ptrCastChance` itself from fuzzer input once at the start of the test. So, instead of all examples having the same average ratio of pointer casts, you can get examples which are mostly pointer casts, and examples which are hardly ever pointer casts. And SWARM testing literature (and common sense) tells that the latter is potentially more interesting.
Author
Contributor
Copy link

Interesting idea. Note that the current fuzzer implementation does not effectively support swarm testing as it reuses previous values independent of their current weights (as long as it is still valid). Also, the use for this Ratio type is already fulfilled by storing the ratio with []const Weight and using valueWeighted, which also avoids having to reconstruct the weights each time. And as such, boolWeighted(a, b) can be viewed as a shorthand for valueWeighted(bool, ratio(a, b)).

Interesting idea. Note that the current fuzzer implementation does not effectively support swarm testing as it reuses previous values independent of their current weights (as long as it is still valid). Also, the use for this Ratio type is already fulfilled by storing the ratio with `[]const Weight` and using `valueWeighted`, which also avoids having to reconstruct the weights each time. And as such, `boolWeighted(a, b)` can be viewed as a shorthand for `valueWeighted(bool, ratio(a, b))`.
@ -0,0 +2470,4 @@
trya.addSource(ids[a.smith.valueRangeLessThan(u32,0,@intCast(ids.len))]);
}else{
constids=std.zig.BuiltinFn.list.keys();
trya.addSource(ids[a.smith.valueRangeLessThan(u32,0,@intCast(ids.len))]);
Contributor
Copy link

Yeah, selecting a random item of a list is a fairly frequent use-case. For TB, we have an API that gives you a random index:

ids[a.smith.index(ids)];

This seems like a sweat spot --- the API that gives you item needs to be polymorphic with respect to const, and doesn't work for parallel array. But the API that gives you just the index works for all these cases and is fairly convenient.

Yeah, selecting a random item of a list is a fairly frequent use-case. For TB, we have an API that gives you a random index: ``` ids[a.smith.index(ids)]; ``` This seems like a sweat spot --- the API that gives you _item_ needs to be polymorphic with respect to `const`, and doesn't work for parallel array. But the API that gives you _just_ the index works for all these cases and is fairly convenient.
Author
Contributor
Copy link

I don't see any problem with such a function (except it should take ids.len instead to avoid being a generic function) and it does come up quite a few times in this. I will add this if I need to push the branch since it is not strictly necessary.

I don't see any problem with such a function (except it should take `ids.len` instead to avoid being a generic function) and it does come up quite a few times in this. I will add this if I need to push the branch since it is not strictly necessary.
gooncreeper marked this conversation as resolved
gooncreeper force-pushed ast-smith from 2f54569e7b
Some checks failed
ci / x86_64-netbsd-release (pull_request) Successful in 34m2s
ci / x86_64-freebsd-release (pull_request) Successful in 35m3s
ci / aarch64-macos-release (pull_request) Successful in 48m34s
ci / x86_64-freebsd-debug (pull_request) Successful in 48m16s
ci / x86_64-netbsd-debug (pull_request) Successful in 51m7s
ci / x86_64-openbsd-release (pull_request) Successful in 55m3s
ci / x86_64-linux-debug (pull_request) Successful in 55m59s
ci / x86_64-windows-release (pull_request) Successful in 59m26s
ci / x86_64-openbsd-debug (pull_request) Successful in 1h7m0s
ci / x86_64-windows-debug (pull_request) Successful in 1h12m12s
ci / aarch64-macos-debug (pull_request) Successful in 1h13m28s
ci / aarch64-linux-release (pull_request) Successful in 1h31m25s
ci / powerpc64le-linux-release (pull_request) Successful in 1h40m16s
ci / s390x-linux-release (pull_request) Successful in 2h5m6s
ci / x86_64-linux-debug-llvm (pull_request) Successful in 2h10m36s
ci / x86_64-linux-release (pull_request) Successful in 2h16m1s
ci / aarch64-linux-debug (pull_request) Successful in 2h44m16s
ci / s390x-linux-debug (pull_request) Successful in 3h16m58s
ci / powerpc64le-linux-debug (pull_request) Successful in 4h12m10s
ci / loongarch64-linux-debug (pull_request) Successful in 3h59m25s
ci / riscv64-linux-debug (pull_request) Has been skipped
ci / riscv64-linux-release (pull_request) Has been skipped
ci / aarch64-netbsd-debug (pull_request) Successful in 3h51m44s
ci / aarch64-netbsd-release (pull_request) Successful in 2h27m49s
ci / aarch64-freebsd-debug (pull_request) Successful in 3h21m43s
ci / aarch64-freebsd-release (pull_request) Successful in 2h55m16s
ci / loongarch64-linux-release (pull_request) Failing after 1h15m37s
to 0b52cac434
All checks were successful
ci / x86_64-netbsd-release (pull_request) Successful in 34m19s
ci / x86_64-freebsd-release (pull_request) Successful in 34m54s
ci / aarch64-macos-release (pull_request) Successful in 42m21s
ci / x86_64-netbsd-debug (pull_request) Successful in 44m3s
ci / x86_64-freebsd-debug (pull_request) Successful in 45m6s
ci / x86_64-openbsd-release (pull_request) Successful in 50m7s
ci / x86_64-openbsd-debug (pull_request) Successful in 1h0m38s
ci / aarch64-macos-debug (pull_request) Successful in 1h2m14s
ci / aarch64-linux-release (pull_request) Successful in 1h30m45s
ci / x86_64-linux-debug (pull_request) Successful in 1h36m59s
ci / x86_64-windows-release (pull_request) Successful in 53m55s
ci / aarch64-linux-debug (pull_request) Successful in 2h37m54s
ci / x86_64-linux-debug-llvm (pull_request) Successful in 2h44m46s
ci / x86_64-linux-release (pull_request) Successful in 2h21m48s
ci / x86_64-windows-debug (pull_request) Successful in 1h15m36s
ci / s390x-linux-release (pull_request) Successful in 1h51m42s
ci / s390x-linux-debug (pull_request) Successful in 3h7m3s
ci / powerpc64le-linux-release (pull_request) Successful in 1h52m43s
ci / powerpc64le-linux-debug (pull_request) Successful in 5h2m26s
ci / loongarch64-linux-release (pull_request) Successful in 2h19m20s
ci / loongarch64-linux-debug (pull_request) Successful in 3h23m5s
ci / riscv64-linux-debug (pull_request) Has been skipped
ci / riscv64-linux-release (pull_request) Has been skipped
ci / aarch64-freebsd-debug (pull_request) Successful in 3h27m34s
ci / aarch64-netbsd-release (pull_request) Successful in 2h44m36s
ci / aarch64-freebsd-release (pull_request) Successful in 2h49m32s
ci / aarch64-netbsd-debug (pull_request) Successful in 4h12m3s
2026年03月25日 22:33:33 +01:00
Compare
andrewrk left a comment
Copy link

Brilliant!

Brilliant!
@ -0,0 +11,4 @@
smith:*Smith,
source_buf:[16384]u8,
Owner
Copy link

Lately I've come to the conclusion that pretty much any buffer in a struct which has more than one reasonable value should be a slice, with externally provided memory (rather than an array, embedded within the struct).

I won't make this block the PR from landing, but I wanted to offer you this consideration and see what you think about it.

Lately I've come to the conclusion that pretty much any buffer in a struct which has more than one reasonable value should be a slice, with externally provided memory (rather than an array, embedded within the struct). I won't make this block the PR from landing, but I wanted to offer you this consideration and see what you think about it.
@ -2953,4 +2969,0 @@
_=p.eatToken(.colon)orelse{
if(p.tokenTag(p.tok_i)==.l_parenand
p.tokensOnSameLine(p.tok_i-1,p.tok_i))
returnp.fail(.expected_continue_expr);
Contributor
Copy link

Was this intentional?

before:

0.16.0-dev.3061+9b1eaad13
> zig run new_while.zig
new_while.zig:4:20: error: expected ':' before while continue expression
 while (i != 0) (i -= 1) {std.debug.print("i = {}", .{i});}
 ^

after:

0.16.0-dev.3100+ce3f25452
> zig run new_while.zig
new_while.zig:4:23: error: expected ')', found '-='
 while (i != 0) (i -= 1) {std.debug.print("i = {}", .{i});}
 ^~
Was this intentional? before: ``` 0.16.0-dev.3061+9b1eaad13 > zig run new_while.zig new_while.zig:4:20: error: expected ':' before while continue expression while (i != 0) (i -= 1) {std.debug.print("i = {}", .{i});} ^ ``` after: ``` 0.16.0-dev.3100+ce3f25452 > zig run new_while.zig new_while.zig:4:23: error: expected ')', found '-=' while (i != 0) (i -= 1) {std.debug.print("i = {}", .{i});} ^~ ```
Author
Contributor
Copy link

Yes. It's to allow while (i != 0) (expr) without a newline between the parenthesis, which is consistent with the PEG. I do agree the new error is a bit worse but the old behavior was incorrect as it was.

Yes. It's to allow `while (i != 0) (expr)` without a newline between the parenthesis, which is consistent with the PEG. I do agree the new error is a bit worse but the old behavior was incorrect as it was.
Sign in to join this conversation.
No reviewers
Labels
Clear labels
abi/f32
abi/ilp32
abi/sf
accepted
This proposal is planned.
arch/21k
arch/6502
arch/aarch64
arch/alpha
arch/amdgcn
arch/arc
arch/arc32
arch/arc64
arch/arm
arch/avr
arch/bfin
arch/bpf
arch/colossus
arch/cris
arch/csky
arch/dlx
arch/epiphany
arch/fr30
arch/frv
arch/hexagon
arch/hppa
arch/hppa64
arch/ia64
arch/kalimba
arch/kvx
arch/lanai
arch/lm32
arch/loongarch32
arch/loongarch64
arch/m32r
arch/m68k
arch/m88k
arch/mcore
arch/microblaze
arch/mips
arch/mips64
arch/mmix
arch/moxie
arch/mrisc32
arch/msp430
arch/nds32
arch/ns32k
arch/nvptx
arch/or1k
arch/powerpc
arch/powerpc64
arch/propeller
arch/riscv32
arch/riscv64
arch/rl78
arch/rx
arch/s390x
arch/sh
arch/sparc
arch/sparc64
arch/spirv
arch/spu
arch/tricore
arch/v850
arch/vax
arch/vc4
arch/ve
arch/wasm
arch/x86
arch/x86_64
arch/xcore
arch/xtensa
autodoc
The web application for interactive documentation and generation of its assets.
backend/c
The C backend outputs C source code.
backend/llvm
The LLVM backend outputs an LLVM bitcode module.
backend/self-hosted
The self-hosted backends produce machine code directly.
binutils
Zig's included binary utilities: zig ar, zig dlltool, zig lib, zig ranlib, zig objcopy, and zig rc.
breaking
Implementing this issue could cause existing code to no longer compile or have different behavior.
build system
The Zig build system - zig build, std.Build, the build runner, and package management.
debug info
An issue related to debug information (e.g. DWARF) produced by the Zig compiler.
docs
An issue with documentation, e.g. the language reference or standard library doc comments.
error message
This issue points out an error message that is unhelpful and should be improved.
frontend
Tokenization, parsing, AstGen, ZonGen, Sema, Legalize, and Liveness.
fuzzing
An issue related to Zig's integrated fuzz testing.
incremental
Reuse of internal compiler state for faster compilation.
lib/c
This issue relates to Zig's libc implementation and/or vendored libcs.
lib/compiler-rt
This issue relates to Zig's compiler-rt library.
lib/cxx
This issue relates to Zig's vendored libc++ and/or libc++abi.
lib/std
This issue relates to Zig's standard library.
lib/tsan
This issue relates to Zig's vendored libtsan.
lib/ubsan-rt
This issue relates to Zig's ubsan-rt library.
lib/unwind
This issue relates to Zig's vendored libunwind.
linking
Zig's integrated object file and incremental linker.
miscompilation
The compiler reports success but produces semantically incorrect code.
os/android
os/contiki
os/dragonfly
os/driverkit
os/emscripten
os/freebsd
os/fuchsia
os/haiku
os/hermit
os/hurd
os/illumos
os/ios
os/linux
os/maccatalyst
os/macos
os/managarm
os/netbsd
os/ohos
os/openbsd
os/plan9
os/redox
os/rtems
os/serenity
os/tvos
os/uefi
os/visionos
os/wasi
os/watchos
os/windows
proposal
This issue suggests language modifications. If it also has the "accepted" label then it is planned.
release notes
This issue or pull request should be mentioned in the release notes.
testing
This issue is related to testing the compiler, standard library, or other parts of Zig.
zig cc
Zig as a drop-in C-family compiler.
zig fmt
The Zig source code formatter.
zig reduce
The Zig source code reduction tool.
bounty
https://ziglang.org/news/announcing-donor-bounties
bug
Observed behavior contradicts documented or intended behavior.
contributor-friendly
This issue is limited in scope and/or knowledge of project internals.
downstream
An issue with a third-party project that uses this project.
enhancement
Solving this issue will likely involve adding new logic or components to the codebase.
infra
An issue related to project infrastructure, e.g. continuous integration.
optimization
A task to improve performance and/or resource usage.
question
No questions on the issue tracker; use a community space instead.
regression
Something that used to work in a previous version stopped working
upstream
An issue with a third-party project that this project uses.
use case
Describes a real use case that is difficult or impossible, but does not propose a solution.
No labels
abi/f32
abi/ilp32
abi/sf
accepted
arch/21k
arch/6502
arch/aarch64
arch/alpha
arch/amdgcn
arch/arc
arch/arc32
arch/arc64
arch/arm
arch/avr
arch/bfin
arch/bpf
arch/colossus
arch/cris
arch/csky
arch/dlx
arch/epiphany
arch/fr30
arch/frv
arch/hexagon
arch/hppa
arch/hppa64
arch/ia64
arch/kalimba
arch/kvx
arch/lanai
arch/lm32
arch/loongarch32
arch/loongarch64
arch/m32r
arch/m68k
arch/m88k
arch/mcore
arch/microblaze
arch/mips
arch/mips64
arch/mmix
arch/moxie
arch/mrisc32
arch/msp430
arch/nds32
arch/ns32k
arch/nvptx
arch/or1k
arch/powerpc
arch/powerpc64
arch/propeller
arch/riscv32
arch/riscv64
arch/rl78
arch/rx
arch/s390x
arch/sh
arch/sparc
arch/sparc64
arch/spirv
arch/spu
arch/tricore
arch/v850
arch/vax
arch/vc4
arch/ve
arch/wasm
arch/x86
arch/x86_64
arch/xcore
arch/xtensa
autodoc
backend/c
backend/llvm
backend/self-hosted
binutils
breaking
build system
debug info
docs
error message
frontend
fuzzing
incremental
lib/c
lib/compiler-rt
lib/cxx
lib/std
lib/tsan
lib/ubsan-rt
lib/unwind
linking
miscompilation
os/android
os/contiki
os/dragonfly
os/driverkit
os/emscripten
os/freebsd
os/fuchsia
os/haiku
os/hermit
os/hurd
os/illumos
os/ios
os/linux
os/maccatalyst
os/macos
os/managarm
os/netbsd
os/ohos
os/openbsd
os/plan9
os/redox
os/rtems
os/serenity
os/tvos
os/uefi
os/visionos
os/wasi
os/watchos
os/windows
proposal
release notes
testing
zig cc
zig fmt
zig reduce
bounty
bug
contributor-friendly
downstream
enhancement
infra
optimization
question
regression
upstream
use case
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
5 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ziglang/zig!31635
Reference in a new issue
ziglang/zig
No description provided.
Delete branch "gooncreeper/zig:ast-smith"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?