31917 Commits

Author SHA1 Message Date
Alex Rønne Petersen
c666ebb1f8
musl: Add unwinding protection in clone() implementations.
Whatever was in the frame pointer register prior to clone() will no longer be
valid in the child process, so zero it to protect FP-based unwinders. This is
just an extension of what was already done for i386 and x86_64. Only applied
to architectures where the _start() code also zeroes the frame pointer.
2024-12-11 00:10:17 +01:00
Alex Rønne Petersen
da018f9726
std.os.linux: Add unwinding protection in clone() implementations.
Whatever was in the frame pointer register prior to clone() will no longer be
valid in the child process, so zero it to protect FP-based unwinders. Similarly,
mark the link register as undefined to protect DWARF-based unwinders.

This is only zeroing the frame pointer(s) on Arm/Thumb because of an LLVM
assembler bug: https://github.com/llvm/llvm-project/issues/115891
2024-12-11 00:10:17 +01:00
Alex Rønne Petersen
7d00877076
start: Extend DWARF unwinding protection to more architectures.
The function is not marked .cantunwind for Arm/Thumb because of an LLVM
assembler bug: https://github.com/llvm/llvm-project/issues/115891
2024-12-11 00:10:17 +01:00
Alex Rønne Petersen
43b6bd4243
start: Zero the link and frame pointer registers on all architectures. 2024-12-11 00:10:17 +01:00
Alex Rønne Petersen
8af82621d7
compiler: Improve the handling of unwind table levels.
The goal here is to support both levels of unwind tables (sync and async) in
zig cc and zig build. Previously, the LLVM backend always used async tables
while zig cc was partially influenced by whatever was Clang's default.
2024-12-11 00:10:15 +01:00
Alex Rønne Petersen
0b67463b92
riscv64: Support the fp alias for register s0 in inline assembly. 2024-12-11 00:09:22 +01:00
saurabh
c172877b81
std.posix: map errno 6 (ENXIO) to error.NoDevice in write() (#22113)
Co-authored-by: Saurabh <saurabhm@proton.me>
2024-12-11 00:06:51 +01:00
Travis Lange
414fc3b207 fix unknown file extension with rmeta 2024-12-10 21:12:55 +01:00
Andrew Kelley
7575f21212
Merge pull request #22157 from mlugg/astgen-error-lazy
compiler: allow semantic analysis of files with AstGen errors
2024-12-09 18:32:23 -05:00
Andrew Kelley
8245d7fac0
Merge pull request #22164 from mlugg/astgen-ref-dedup
AstGen: correctly deduplicate `ref` of `param` and `alloc_inferred`
2024-12-09 18:04:26 -05:00
mlugg
3aab81b0ab Builtin: clean up formatting of generated code
This commit simply tweaks the generated `builtin.zig` source code to be
more consistent and in line with current conventions.
2024-12-09 17:35:10 -05:00
Alex Rønne Petersen
b94bb6f96f std.Target: Remove our broken support for the ancient and obsolete Arm OABI.
NetBSD has long since migrated to the EABI and doesn't officially support the
OABI anymore. The ABI selection logic in LLVM only actually picks OABI for
NetBSD as a last resort if the EABI isn't selected. That fallback is likely to
be removed in the future. So just remove this support in Zig entirely.

While here, I also removed some leftover 32-bit Arm and 32-bit x86 code for
Apple targets, which are long dead and unsupported by Zig.
2024-12-09 10:47:18 +01:00
Alex Rønne Petersen
7cd2c1ce87
Merge pull request #22191 from alexrp/wasi-libc-names
`std.zig.target`: Teach `isLibCLibName()` about emulated wasi-libc libraries
2024-12-09 10:46:56 +01:00
Alex Rønne Petersen
589f4e9170
Merge pull request #22190 from alexrp/cc-args
`Compilation`: Don't rely on Clang defaults for options that are user-facing.
2024-12-09 10:46:31 +01:00
Alex Rønne Petersen
c9e74bb9aa
std.zig.target: Teach isLibCLibName() about emulated wasi-libc libraries. 2024-12-08 20:23:58 +01:00
Alex Rønne Petersen
f283791a5e
compiler: Link libc when we're asked to link to an emulated wasi-libc library. 2024-12-08 20:22:13 +01:00
Alex Rønne Petersen
1e095024a7
compiler: Check for wasi-libc emulated libraries before libc libraries.
This will become useful when we update wasi-libc and get the emulated libdl.
2024-12-08 20:20:54 +01:00
Alex Rønne Petersen
92117d9bef
std.zig.target: Remove duplicate libc check for macOS in isLibCLibName(). 2024-12-08 20:18:01 +01:00
wooster0
a221b2fbf2 Sema: fix use of Zcu.LazySrcLoc in error message
It currently prints as:

:3:18: error: untagged union 'Zcu.LazySrcLoc{ .base_node_inst = InternPool.TrackedInst.Index(104), .offset = Zcu.LazySrcLoc.Offset{ .node_offset = Zcu.LazySrcLoc.Offset.TracedOffset{ .x = -2, .trace = (value tracing disabled) } } }' cannot be converted to integer
2024-12-08 17:23:57 +00:00
Alex Rønne Petersen
6951ee43bf
Compilation: Don't rely on Clang defaults for options that are user-facing. 2024-12-08 16:53:55 +01:00
Alex Rønne Petersen
8d9ff8353d
compiler: Update the list of targets that have a red zone. 2024-12-08 16:52:44 +01:00
mlugg
135c733eef
InternPool: fix crash in rehashTrackedInsts
When a shard has zero elements, we don't need to reserve any capacity.
2024-12-08 10:53:51 +00:00
Jacob Young
bd0ace5c4e
cbe: prevent tautological-compare warnings in generated code 2024-12-08 10:53:50 +00:00
mlugg
03f5b967f0
AstGen: correctly deduplicate ref of param and alloc_inferred
Both of these instructions were previously under a special case in
`rvalue` which resulted in every reference to such an instruction adding
a new `ref` instruction. This had the effect that, for instance,
`&a != &a` for parameters. Deduplicating these `ref` instructions was
problematic for different reasons.

For `alloc_inferred`, the problem was that it's not valid to `ref` the
alloc until the allocation has been resolved (`resolve_inferred_alloc`),
but `AstGen.appendBodyWithFixups` would place the `ref` directly after
the `alloc_inferred`. This is solved by bringing
`resolve_inferred_alloc` in line with `make_ptr_const` by having it
*return* the final pointer, rather than modifying `sema.inst_map` of the
original `alloc_inferred`. That way, the `ref` refers to the
`resolve_inferred_alloc` instruction, so is placed immediately after it,
avoiding this issue.

For `param`, the problem is a bit trickier: `param` instructions live in
a body which must contain only `param` instructions, then a
`func{,_inferred,_fancy}`, then a `break_inline`. Moreover, `param`
instructions may be referenced not only by the function body, but also
by other parameters, the return type expression, etc. Each of these
bodies requires separate `ref` instructions. This is solved by pulling
entries out of `ref_table` after evaluating each component of the
function declaration, and appending the refs later on when actually
putting the bodies together. This gives way to another issue: if you
write `fn f(x: T) @TypeOf(x.foo())`, then since `x.foo()` takes a
reference to `x`, this `ref` instruction is now in a comptime context
(outside of the `@TypeOf` ZIR body), so emits a compile error. This is
solved by loosening the rules around `ref` instructions; because they
are not side-effecting, it is okay to allow `ref` of runtime values at
comptime, resulting in a runtime-known value in a comptime scope. We
already apply this mechanism in some cases; for instance, it's why
`runtime_array.len` works in a `comptime` context. In future, we will
want to give similar treatment to many operations in Sema: in general,
it's fine to apply runtime operations at comptime provided they don't
have side effects!

Resolves: #22140
2024-12-08 10:53:50 +00:00
Alex Rønne Petersen
e62aac3ec4 compiler: Only omit frame pointers by default for ReleaseSmall.
Frame pointers make both debugging and profiling work better, and the overhead
is reportedly 1% or less for typical programs [0]. I think the pros outweigh the
cons here. People who *really* care about that 1% can simply use the
-fomit-frame-pointer option to reclaim it. For ReleaseSmall, though, it makes
sense to omit frame pointers by default for the sake of code size, as we already
strip the binary in this case anyway.

Closes #22161.

[0] https://www.brendangregg.com/blog/2024-03-17/the-return-of-the-frame-pointers.html
2024-12-08 04:18:12 -05:00
Alex Rønne Petersen
ba37a4369b std.zig.WindowsSdk: Support cross-arch SDK lookups.
This makes e.g. cross-compiling for x86-windows-msvc on a x86_64-windows-msvc
system work properly.

Closes #11926.
2024-12-08 04:53:28 +01:00
Alex Rønne Petersen
1f95e3d9cd build.zig: Also set code model for loongarch32.
This issue applies to both loongarch32 and loongarch64.
2024-12-07 22:21:35 +01:00
Alex Rønne Petersen
4894ac4bcb
Merge pull request #22130 from alexrp/zig-h-portability
Some portability improvements and cleanups in `zig.h`
2024-12-07 12:11:57 +01:00
Andrew Kelley
eb9c9a38f2
Merge pull request #22167 from alexrp/compiler-rt-names
compiler: Classify various compiler-rt and libunwind names accurately and satisfy them
2024-12-06 19:04:39 -05:00
Alex Rønne Petersen
ca069244b2 std.Target: Fix charSignedness() for hexagon. 2024-12-06 18:15:29 +01:00
Alex Rønne Petersen
8f27fc6c07
compiler: Classify libssp as an alias for compiler-rt.
This is a GCC library providing symbols with stack smashing protection. We
provide (most of) these symbols in our compiler-rt.
2024-12-06 15:10:37 +01:00
Alex Rønne Petersen
65cfc91836
std.zig.target: Consider libsupc++ to be a libc++ library name.
This is, roughly, GCC's equivalent of libc++abi.
2024-12-06 15:08:43 +01:00
Alex Rønne Petersen
da794ec7a3
compiler: Remove warning about superfluous compiler-rt libraries.
* This warning's wording is actually inaccurate when using the -fno-compiler-rt
  or -rtlib=none options.
* It's not all that helpful; it's already understood that these libraries are
  part of the compiler, so printing a warning is just noise. In practice, this
  warning would always happen when building upstream musl, for example.
* We don't warn when we satisfy -lunwind using our bundled libunwind either, or
  various libc libraries using our bundled libc, or when providing libc++, etc.
  So I really don't think we should be warning here either.
2024-12-06 14:57:22 +01:00
Alex Rønne Petersen
a879c3ea0b
compiler: Classify libgcc as an alias for compiler-rt.
This is GCC's equivalent to compiler-rt. The two libraries have a huge overlap
in exported symbols, so we may as well satisfy it this way to increase
compatibility with build systems in the wild.
2024-12-06 14:57:22 +01:00
Alex Rønne Petersen
e7169e9d4d
compiler: Classify libgcc_eh as an alias for libunwind.
This is GCC's take on libunwind. We can satisfy it by way of our bundled LLVM
libunwind implementation.

Closes #17268.
2024-12-06 14:57:22 +01:00
Alex Rønne Petersen
37a34b54af
compiler: Recognize libgcc_s regardless of target ABI.
The real libgcc_s is a compiler-provided library; it works just fine with both
glibc and musl. There's no reason that I can see for this check to be limited to
glibc-based targets.
2024-12-06 14:57:19 +01:00
Alex Rønne Petersen
f8372d030e
compiler: Classify libatomic as an alias for compiler-rt.
This is a library that ships with GCC and provides fallback implementations of
atomic intrinsics where necessary. Since we do the same in our compiler-rt
implementation, and since some build systems insist on passing -latomic even
for Clang (which zig cc masquerades as), just satisfy this dependency by way of
compiler-rt.

Closes #22165.
2024-12-06 14:51:22 +01:00
mlugg
9f086f84f5
Zcu: allow test declarations to be failed
The introduction of the `extended(astgen_error())` instruction allows a
`test` declaration to be unresolved, i.e. the declaration doesn't even
contain a `func`. I could modify AstGen to not do this, but it makes
more sense to just handle this case when collecting test functions.

Note that tests under incremental compilation are currently broken if
you ever remove all references to a test; this is tracked as a subtask
of #21165.
2024-12-06 06:22:32 +00:00
mlugg
8f849684f4
std.zig.Zir: improve instruction tracking
The main change here is to partition tracked instructions found within a
declaration. It's very unlikely that, for instance, a `struct { ... }`
type declaration was intentionally turned into a reification or an
anonymous initialization, so it makes sense to track things in a few
different arrays.

In particular, this fixes an issue where a `func` instruction could
wrongly be mapped to something else if the types of function parameters
changed. This would cause huge problems further down the pipeline; we
expect that if a `declaration` is tracked, and it previously contained a
`func`/`func_inferred`/`func_fancy`, then this instruction is either
tracked to another `func`/`func_inferred`/`func_fancy` instruction, or
is lost.

Also, this commit takes the opportunity to rename the functions actually
doing this logic. `Zir.findDecls` was a name that might have made sense
at some point, but nowadays, it's definitely not finding declarations,
and it's not *exclusively* finding type declarations. Instead, the point
is to find instructions which we want to track; hence the new name,
`Zir.findTrackable`.

Lastly, a nice side effect of partitioning the output of `findTrackable`
is that `Zir.declIterator` no longer needs to accept input instructions
which aren't type declarations (e.g. `reify`, `func`).
2024-12-05 19:58:42 +00:00
mlugg
7f3211a101
compiler: incremental compilation fixes
The previous commit exposed some bugs in incremental compilation. This
commit fixes those, and adds a little more logging for debugging
incremental compilation.

Also, allow `ast-check -t` to dump ZIR when there are non-fatal AstGen
errors.
2024-12-05 19:58:42 +00:00
mlugg
4d7818a76a
compiler: allow files with AstGen errors to undergo semantic analysis
This commit enhances AstGen to introduce a form of error resilience
which allows valid ZIR to be emitted even when AstGen errors occur.

When a non-fatal AstGen error (e.g. `appendErrorNode`) occurs, ZIR
generation is not affected; the error is added to `astgen.errors` and
ultimately to the errors stored in `extra`, but that doesn't stop us
getting valid ZIR. Fatal AstGen errors (e.g. `failNode`) are a bit
trickier. These errors return `error.AnalysisFail`, which is propagated
up the stack. In theory, any parent expression can catch this error and
handle it, continuing ZIR generation whilst throwing away whatever was
lost. For now, we only do this in one place: when creating declarations.
If a call to `fnDecl`, `comptimeDecl`, `globalVarDecl`, etc, returns
`error.AnalysisFail`, the `declaration` instruction is still created,
but its body simply contains the new `extended(astgen_error())`
instruction, which instructs Sema to terminate semantic analysis with a
transitive error. This means that a fatal AstGen error causes the
innermost declaration containing the error to fail, but the rest of the
file remains intact.

If a source file contains parse errors, or an `error.AnalysisFail`
happens when lowering the top-level struct (e.g. there is an error in
one of its fields, or a name has multiple declarations), then lowering
for the entire file fails. Alongside the existing `Zir.hasCompileErrors`
query, this commit introduces `Zir.loweringFailed`, which returns `true`
only in this case.

The end result here is that files with AstGen failures will almost
always still emit valid ZIR, and hence can undergo semantic analysis on
the parts of the file which are (from AstGen's perspective) valid. This
is a noteworthy improvement to UX, but the main motivation here is
actually incremental compilation. Previously, AstGen failures caused
lots of semantic analysis work to be thrown out, because all `AnalUnit`s
in the file required re-analysis so as to trigger necessary transitive
failures and remove stored compile errors which would no longer make
sense (because a fresh compilation of this code would not emit those
errors, as the units those errors applied to would fail sooner due to
referencing a failed file). Now, this case only applies when a file has
severe top-level errors, which is far less common than something like
having an unused variable.

Lastly, this commit changes a few errors in `AstGen` to become fatal
when they were previously non-fatal and vice versa. If there is still a
reasonable way to continue AstGen and lower to ZIR after an error, it is
non-fatal; otherwise, it is fatal. For instance, `comptime const`, while
redundant syntax, has a clear meaning we can lower; on the other hand,
using an undeclared identifer has no sane lowering, so must trigger a
fatal error.
2024-12-05 19:58:38 +00:00
Alex Rønne Petersen
cbc05e0b1d Compilation: Consider *.rlib files to be static libraries.
These are produced by rustc: https://rustc-dev-guide.rust-lang.org/backend/libs-and-metadata.html#rlib
2024-12-05 15:05:55 +01:00
Alex Rønne Petersen
d70be200d8
Merge pull request #22141 from alexrp/target-remove-bridgeos
`std.Target`: Remove `Os.Tag.bridgeos`
2024-12-05 15:05:25 +01:00
Frank Denis
c9d6f8b505
Remove parallel variants of AEGIS-MAC (#22146)
The construction is likely to change before standardization
2024-12-04 22:45:07 +00:00
Alex Rønne Petersen
4e29c67eed
llvm: Remove dead targetArch() and targetOs() functions.
These were leftovers from when we used the LLVM API to create modules.
2024-12-03 20:43:20 +01:00
Alex Rønne Petersen
09b39f77b7
std.Target: Remove Os.Tag.bridgeos.
It doesn't appear that targeting bridgeOS is meaningfully supported by Apple.
Even LLVM/Clang appear to have incomplete support for it, suggesting that Apple
never bothered to upstream that support. So there's really no sense in us
pretending to support this.
2024-12-03 20:43:15 +01:00
Alex Kladov
6188cb8e50 sema: add a missing errdefer
This fix doesn't matter at all in the grand scheme of things, but I
think the story behind it is perhaps curious, as it might point at a
design flaw in the Sema's error reporting API. So, a story:

On lobsters, there's a rather heated discussion on the merits on RAII vs
defer. I don't really like participating in heating discussions, but
also sort of can't stop thinking about this.

My own personal experience with Zig's defer and errdefer is that they
are fiddly to get right consistency --- if a program has a lot of
resource management to do, I _always_ mess up at least one
defer/errdefer. I've found my internal peace by just avoiding
spread-out, "pox" resource management, and instead centralizing resource
ownership under one of the following patterns:

* Either the thing is acquired and released in main
* Or main allocates N instances of thing, and then the rest of the code
  explicitly juggles this finite pool of N. Notably, this juggling
  typically doesn't involve defer/errdefer at all, as, at this level of
  precision, there are no `try`s left, so you only code the happy path
* Or there's some sort of arena thing, where a bunch of resources have a
  single owner, the user's don' bother cleaning up their resources, and
  instead the owner does it once at the end.

So I wanted to make a lobster.rs comment in the vein of "yeah, if your
program is mostly about resource management, then Zig could be kinda a
pain, but that's friction tells you something: perhaps your program
shouldn't be about resource management, and instead it should be doing
what it is supposed to do?". And, as an evidence for my claim, I wanted
to point out some large body of Zig code which doesn't have a lot of
errdefers.

So, I cracked opened Sema.zig, `ctrl+f` for `defer`, saw whopping 400
something occupancies, and my heart skipped a bit. Looking at the
occurrences, _some_ of them were non-resource-related usages of defer.
But a lot of them were the following pattern:

```zig
const msg = try sema.errMsg(src, "comptime control flow inside runtime block", .{});
errdefer msg.destroy(sema.gpa);
```

This is exactly the thing that I know _I_ can't get right consistently!
So, at this point, I made a prediction that at least one of `errdefer`s
is missing. So, I looked at the first few `const msg = try` and of
course found one without `errdefer`.

I am at 0.8 that, even with this PR applied, the claim will still stand
--- there will be `errdefer` missing. So it feels like some API
re-design is in order, to make sure individual error messages are not
resources.

Could Sema just own all partially-constructed error messages, and, at a
few known safe-points:

* if the control flow is normal, assert that there are no in-progress
  error messages
* if we are throwing an error, go and release messages immediately?

I am unlikely to do the actual refactor here, but I think it's worth
highlighting the overall pattern here.

PS: I am only 0.9 sure that what I've found is indeed a bug! I don't
understand the code, I did a dumb text search, so I _could_ have made a
fool of myself here :P
2024-12-03 14:18:26 -05:00
Alex Rønne Petersen
c27488a387
zig.h: Add zig_gnuc_asm macro to indicate availability of GNU-style inline asm. 2024-12-03 12:11:05 +01:00
Alex Rønne Petersen
f058b147d3
zig.h: Introduce operating system macros. 2024-12-03 12:07:34 +01:00
Alex Rønne Petersen
084ec97811
zig.h: Introduce object format macros. 2024-12-03 12:07:34 +01:00