I'm having a problem with code like the following on all 4.2.x versions of
gcc (at least on intel and with my port):
unsigned z = 1;
unsigned *foo()
{
return &z;
}
int main(void)
{
z = 1;
*foo() = 0;
return z;
}
When optimisation is enabled, but inlining disabled (-O1 for example) the
compiler appears to fail to recognise that z clobbered by *foo()=0, and
produces code that returns a constant 1. The problem appears to be caused
by foo being marked pure; if I move foo to another compilation unit, to
problem goes away unless I mark the prototype with __attribute__((pure)).
Also the problem goes away if I add a side-effect to foo. Looking at the
tree dumps reveals that this problem appears in the FRE pass - although
I'd guess that the problem could well originate in the earlier alias
analysis pass.
This problem is fixed in 4.3. A binary search through trunk GCC led me to
revision 119502 (Daniel Berlin, 2006-12-04). However, it doesn't look
like it's possible to back-port this change to 4.2, because of the
intervening changes to the files involved. I naively attempted to patch
across the relitively simple changes to tree-ssa-alias.c in 119502, but
not suprisingly that didn't help on its own.
Does anyone recognise this problem? Any help tracking down the cause of
the problem would be very gratefully received - if nothing else I'll have
to re-fix the problem in 4.2. However, my experience hacking the tree
passes is pretty much zero :(
In the long run I can upgrade to 4.3 or 4.4. However, updating my port
and re-validating it is a fair amount of work that I'm not keen to tackle
immediately.
Thanks,
Ned.
--