This is with Pelles C version 8, release candidate 6, 32-bit compiler, with optimisation on (/Ot), running in Windows 7 64-bits.
Take the following code:
typedef struct _varrec {
int dummy1, dummy2;
struct _varrec* ptr;
int dummy3;
} varrec;
int main (void) {
varrec u={0},v={0};
varrec *p;
u.ptr=&v;
p=&u;
*p = *(p->ptr);
}
This copies the 16-byte struct from v to u. As far as I know, this is legal, fully defined C. But it crashes when running the optimised code (which inlines the block copy as a set of four moves).
I think it is to with repeatedly re-evaluating the p->ptr expression, even when it is overwritten by the contents of v. (So with the last of the four 32-bit copies, it writes to location 0).
This is part of a disassembly of the code:
0040531A 8B4608 mov eax,[esi+8]
0040531D 8B00 mov eax,[eax]
0040531F 8907 mov [edi],eax
00405321 8B4608 mov eax,[esi+8]
00405324 8B4004 mov eax,[eax+4]
00405327 894704 mov [edi+4],eax
0040532A 8B4608 mov eax,[esi+8]
0040532D 8B4008 mov eax,[eax+8]
00405330 894708 mov [edi+8],eax
00405333 8B4608 mov eax,[esi+8]
00405336 8B400C mov eax,[eax+0Ch]
00405339 89470C mov [edi+0Ch],eax
It seem to be the repeated [esi+8] that is the culprit. (Perhaps needs a lea esi,[esi+8] at the top, then it uses [esi].)