This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c/30553] New: Registers not spilled to the stack properly when accessing address of parameter in function call
- From: "sb at anoto dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 23 Jan 2007 04:59:42 -0000
- Subject: [Bug c/30553] New: Registers not spilled to the stack properly when accessing address of parameter in function call
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
To get the binary int of a double, it is common to cast the ptr to the double
to an int ptr and then access the data the pointer points to. However, if the
variable containing the double is a function call parameter and the parameter
is passed in registers and hasn't been spilled to the stack yet, the pointer
access will be accessing uninitialized stack space:
Example:
arm-elf-gcc -Os -mthumb
int myfunc(double x)
{
int a;
a = *(int *)&x; // x isn't spilled to the stack before the * access is
done
return a+2;
}
int myfunc2(int x)
{
int a;
a = *(int *)&x; // gcc figures out that it doesn't have to go through
memory to do the access
return a+2;
}
extern void dummy(void);
int myfunc3(double x)
{
int a;
dummy(); // This function call forces gcc to spill x (r0 and r1) to
memory
a = *(int *)&x;
return a+2;
}
The disassembly is:
00000000 <myfunc>:
0: b082 sub sp, #8
2: 9800 ldr r0, [sp, #0] ; reading from [sp, #0] where r0
should have been saved. Error!
4: b002 add sp, #8
6: 3002 add r0, #2
8: 4770 bx lr
...
0000000c <myfunc2>:
c: 3002 add r0, #2 ; Doesn't have to go through the stack.
OK!
e: 4770 bx lr
00000010 <myfunc3>:
10: b500 push {lr}
12: b082 sub sp, #8
14: 9000 str r0, [sp, #0] ; Aha! r0 is correctly spilled to
the stack to be able to make the function call below
16: 9101 str r1, [sp, #4]
18: fffef7ff bl 0 <dummy>
1c: 9800 ldr r0, [sp, #0] ; Reading from the stack now gives
the correct result. OK!
1e: b002 add sp, #8
20: 3002 add r0, #2
22: bd00 pop {pc}
The problem appears for both thumb and normal arm code. I guess the same thing
can happen on any platform that passes the initial parameters in registers
--
Summary: Registers not spilled to the stack properly when
accessing address of parameter in function call
Product: gcc
Version: 4.1.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: sb at anoto dot com
GCC build triplet: x86-pc-cygwin
GCC host triplet: x86-pc-cygwin
GCC target triplet: arm-elf-gcc
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30553