------- Comment #12 from lordhoto at gmail dot com 2009-09-15 21:24 ------- Happens for me too on Linux/AMD64 with:
gcc (Debian 4.3.4-2) 4.3.4 and gcc (Debian 4.4.1-4) 4.4.1 It also happens with structs of sizes 3, 5 and 7 for me. An easy (non-runtime) test case for different struct sizes can be made via: struct test { unsigned char size[TEST_SIZE]; }; void bar(struct test); void foo(struct test *t) { bar(*t); } Just define the struct size via "-DTEST_SIZE=size", where "size" is the desired size of the struct, on the gcc command line. One can witness that for struct sizes of 1, 2, 4, 8 and everything above 8 it works just fine. Here's the assembly output, generated via 4.3.4, for the working struct sizes: struct size of 1: movq -8(%rbp), %rax movzbl (%rax), %edi call bar struct size of 2: movq -8(%rbp), %rax movzwl (%rax), %edi call bar struct size of 4: movq -8(%rbp), %rax movl (%rax), %edi call bar struct size of 8: movq -8(%rbp), %rax movq (%rax), %edi call bar For all sizes above 8, it does also generate correct assembly, that means it will only read the correct number of bytes. Here is an example with a struct size of 11: movq -8(%rbp), %rdx movq (%rdx), %rdi movzbl 8(%rdx), %ecx movzbl 9(%rdx), %eax salq $8, %rax orq %rax, %rcx movzbl 10(%rdx), %eax salq $16, %rax movq %rax, %rsi orq %rcx, %rsi call bar As you can see it uses one "movq" to read eight bytes at once and then three "movzbl" to read the remaining three bytes. The assembly for this case was generated with -O0. It will look differently for other optimization levels, but is still using the same basic logic. For struct sizes of 3, 5, 6 or 7 the compiler always generates: movq -8(%rbp), %rax movq (%rax), %rdi call bar for me, which is the reported incorrect behavior. -- lordhoto at gmail dot com changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |lordhoto at gmail dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36043