http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52244
Bug #: 52244
Summary: [4.5/4.6/4.7 Regression] wrong code for function
returning union between int and _Bool at O > 2, with
no-early-inlining
Classification: Unclassified
Product: gcc
Version: 4.7.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
AssignedTo: [email protected]
ReportedBy: [email protected]
CC: [email protected]
Target: powerpc-*-darwin9
This was revealed by the test-case attached to PR51528.
in the following:
extern void abort (void);
typedef union u_r
{
_Bool b;
int c;
} u_t;
u_t
bar (void)
{
u_t u;
u.c = 0x1234;
return u;
}
u_t __attribute__ ((noinline))
foo (void)
{
u_t u;
u.b = 1;
u = bar ();
return u;
}
int main (int argc, char **argv)
{
u_t u = foo ();
if (u.c != 0x1234)
abort ();
return 0;
}
====
for -O2 -fno-early-inlining (at m32)
foo is compiled as (wrong):
.globl _foo
_foo:
li r9,0
stw r9,0(r3)
blr
instead of (correct):
.globl _foo
_foo:
li r2,4660
stw r2,0(r3)
blr
======
It only appears to happen for the case where the union is with an item of the
same size as _Bool (which is 32 bits on powerpc-darwin). Replacing 'c' with a
short or a long long or even char[4] will cause the problem to vanish.
======