Some things that used to be allowed in callconv(.Naked)
functions are now compile errors:
- runtime calls
- explicit returns
- runtime safety checks (which produce runtime calls)
Runtime calls are disallowed because it is not possible to know the current stack alignment in order to follow the proper ABI to automatically compile a call. Explicit returns are disallowed because on some targets, it is not mandated for the return address to be stored in a consistent place.
The most common kind of upgrade that needs to be performed is:
export fn _start() callconv(.Naked) noreturn {
asm volatile (
\\ push %rbp
\\ jmp %[start:P]
:
: [start] "X" (&start),
);
unreachable;
}
fn start() void {}
$ zig build-obj repro.zig
repro.zig:8:5: error: runtime safety check not allowed in naked function
unreachable;
^~~~~~~~~~~
repro.zig:8:5: note: use @setRuntimeSafety to disable runtime safety
repro.zig:8:5: note: the end of a naked function is implicitly unreachable
As the note indicates, an explicit unreachable
is not needed at the end of a naked function anymore. Since explicit returns
are no longer allowed, it will just be assumed to be unreachable. Therefore, all that needs to be done is to delete the
unreachable
statement, which works even when the return type of the function is not void
.
In general, naked functions should only contain comptime logic and asm volatile
statements, which allows any required
target-specific runtime calls and returns to be constructed.