http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52565
Bug #: 52565
Summary: __builtin_va_arg(va, double); may fall on cortex-m3
Classification: Unclassified
Product: gcc
Version: 4.6.2
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
AssignedTo: [email protected]
ReportedBy: [email protected]
Created attachment 26880
--> http://gcc.gnu.org/bugzilla/attachment.cgi?id=26880
source and full outputs
Compiling this:
extern double vargTest(const char* format, ...);
#include <stdarg.h>
int main(void) {
vargTest("%f", (double) 1.23456);
while (1)
;
}
double vargTest(const char* format, ...) {
__gnuc_va_list vaList;
__builtin_va_start(vaList, format);
double value = __builtin_va_arg(vaList, double);
return value;
}
void _exit(){
}
Produces:
000080d8 <main>:
80d8: b580 push {r7, lr}
80da: af00 add r7, sp, #0
80dc: f248 4008 movw r0, #33800 ; 0x8408
80e0: f2c0 0000 movt r0, #0
80e4: a302 add r3, pc, #8 ; (adr r3, 80f0 <main+0x18>)
80e6: e9d3 2300 ldrd r2, r3, [r3]
80ea: f000 f805 bl 80f8 <vargTest>
80ee: e7fe b.n 80ee <main+0x16>
80f0: fc8f3238 .word 0xfc8f3238
80f4: 3ff3c0c1 .word 0x3ff3c0c1
000080f8 <vargTest>:
80f8: b40f push {r0, r1, r2, r3}
80fa: b480 push {r7}
80fc: b085 sub sp, #20
80fe: af00 add r7, sp, #0
8100: f107 031c add.w r3, r7, #28
8104: 607b str r3, [r7, #4]
8106: 687b ldr r3, [r7, #4]
8108: f103 0307 add.w r3, r3, #7
810c: f023 0307 bic.w r3, r3, #7
8110: f103 0208 add.w r2, r3, #8
8114: 607a str r2, [r7, #4]
8116: e9d3 2300 ldrd r2, r3, [r3]
811a: e9c7 2302 strd r2, r3, [r7, #8]
811e: e9d7 2302 ldrd r2, r3, [r7, #8]
8122: 4610 mov r0, r2
8124: 4619 mov r1, r3
8126: f107 0714 add.w r7, r7, #20
812a: 46bd mov sp, r7
812c: bc80 pop {r7}
812e: b004 add sp, #16
8130: 4770 bx lr
8132: bf00 nop
The instruction at 0x810c forces the address used for the ldrd to be alligned
to an 8 bytes boundary. The problem is that the double parameter is passed on
register r2-r3 and pushed on the stack at the entry point of vargTest
function. Since the stack is aligned on 4 bytes boundary only the double value
may be misaligned and as a consequence the __builtin_va_arg(vaList, double)
function fails to retrive the correct value.
Is this a bug?