https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125798
Bug ID: 125798
Summary: RISC-V: naked attribute does not suppress varargs
register saves in prologue
Product: gcc
Version: 15.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: bigmagicreadsun at gmail dot com
Target Milestone: ---
When a function is declared with both the "naked" attribute and a variadic
parameter list, the compiler still emits register save instructions at the
function entry to spill unnamed argument registers (a1-a7) to the stack.
This contradicts the documented semantics of "naked", which states that
"the specified function will not have prologue/epilogue sequences generated
by the compiler."
Other back ends (e.g., ARM) handle this correctly by checking for the
naked attribute at the top of their setup_incoming_varargs implementation
and returning early.
1. Compile the following test case with a RISC-V toolchain:
#include <stdarg.h>
__attribute__((naked))
int my_varadd(int count, ...)
{
__asm__ volatile (
"mv a0, zero\n\t"
"ret"
);
}
int main(void)
{
return my_varadd(3, 10, 20, 30);
}
Command: riscv64-unknown-elf-gcc -O2 -S -o- test.c
Expected output:
my_varadd:
mv a0, zero
ret
No register save instructions should be emitted by the compiler for
a naked function.
Actual output:
my_varadd:
sd a1,8(sp)
sd a2,16(sp)
sd a3,24(sp)
sd a4,32(sp)
sd a5,40(sp)
sd a6,48(sp)
sd a7,56(sp)
mv a0, zero
ret
The sd instructions are emitted by riscv_setup_incoming_varargs,
and since the prologue is suppressed (SP not decremented), they
store into the caller's stack frame.