On 03/09/2010 06:54 PM, Thomas Martitz wrote: > Am 09.03.2010 19:36, schrieb Andrew Haley: >> That does not surprise me. I think you're seeing a problem that is >> caused by something elsewhere in your program. I'm guessing that >> there may be a bad prototype or somesuch. >> >> I think you need to strip down your sources until you find something. >> >> Maybe you should try -save-temps and have a look at the actual >> preprocessd source. Maybe some bastard has done >> >> #define int long >> >> or something evil like that! >> >> Andrew. >> > > No, I know our codebase pretty well. This is not the problem. Not that > int or long matters, anyway. > > In the mean time we found a test case: > > ---- > void foo(int last, char * block); > > void bar(void) > { > struct { > char * __attribute__((aligned(8))) member; > } s; > > foo(0,s.member); > } > ---- > > compiled with arm-elf-eabi-gcc -c test.c > > This example exposes the problem. > > We found the problem is related to struct addressing and the aligned > attribute. > > - normal stack variables work > - struct members work with __attribute__((aligned(4))) > - struct members with __attribute__((aligned(X))) where X >= 8 *do not* > work. > > Look at the assembly output for this very example. block is passed in > r2, while it's supposed to be passed in r1. > > Our temporary "fix" is to make it "void foo(int last, volatile char * > block);" [notice the volatile keyword] and it works as well (block > passed in r1). > > This is definitely a gcc bug. The generated call is dependent on the > parameter passed. The callee can't know about this. And it also happens > with -O0. Yeah, it's a bug. Mind you, it's pretty bizarre code: I'm not surprised we never came across this before. Why are you doing this, anyway? I would have expected char __attribute__((aligned(8))) *member; for a pointer to an 8-aligned buffer... Andrew.