A long long bitfield of size 32 is passed to a function taking an int argument
using two argument slots. Adding an explicit cast solves the problem.
Testcase:
#include <stdio.h>
typedef struct {
long long item : 32;
} tester;
void dosomething(int i, int j)
{
printf("i = %#x, j = %#x\n", i, j);
}
void foo(tester bar)
{
dosomething(bar.item, 0);
}
int main(void)
{
tester test;
test.item = 0xabcdef01;
foo(test);
return(0);
}
Asm:
.align 2
.globl _Z3foo6tester
.type _Z3foo6tester, @function
_Z3foo6tester:
.LFB3:
pushl %ebp
.LCFI3:
movl %esp, %ebp
.LCFI4:
subl $24, %esp
.LCFI5:
movl 8(%ebp), %eax
movl %eax, %edx
sarl $31, %edx
movl $0, 8(%esp)
movl %eax, (%esp)
movl %edx, 4(%esp)
call _Z11dosomethingii
leave
ret
.LFE3:
.size _Z3foo6tester, .-_Z3foo6tester
Output:
i = 0xabcdef01, j = 0xffffffff
With explicit cast:
void foo(tester bar)
{
dosomething((int)bar.item, 0);
}
Asm:
.align 2
.globl _Z3foo6tester
.type _Z3foo6tester, @function
_Z3foo6tester:
.LFB3:
pushl %ebp
.LCFI3:
movl %esp, %ebp
.LCFI4:
subl $8, %esp
.LCFI5:
movl 8(%ebp), %eax
movl $0, 4(%esp)
movl %eax, (%esp)
call _Z11dosomethingii
leave
ret
.LFE3:
.size _Z3foo6tester, .-_Z3foo6tester
Output:
i = 0xabcdef01, j = 0
--
Summary: long long bitfield passed to int argument incorrectly
Product: gcc
Version: 4.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: greened at obbligato dot org
GCC build triplet: i686-pc-linux-gnu
GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32346