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

Reply via email to