------- Comment #5 from rguenth at gcc dot gnu dot org 2008-03-29 10:52 -------
Here's a shorter testcase:
struct object { int one_o; int allocstamp; };
int pgci_pointable (object obj);
void foo(void);
int main (int argc, char *argv[])
{
if (pgci_pointable((object){7,100}))
{
bad_rehash_size:
foo();
}
goto bad_rehash_size;
}
If you look at the original IL as coming from the FE you see
{
<<cleanup_point struct object D.1681 = {.one_o=7, .allocstamp=100};>>;
<<< Unknown tree: if_stmt
<<cleanup_point pgci_pointable (D.1681) != 0>>
bad_rehash_size:;
<<cleanup_point <<< Unknown tree: expr_stmt foo () >>> >>;
>>> ;
}
goto bad_rehash_size;
which is gimplified to
{
{
struct objectD.1670 D.1681;
D.1681.one_oD.1672 = 7;
D.1681.allocstampD.1673 = 100;
D.1699 = pgci_pointable (D.1681);
retval.0D.1698 = D.1699 != 0;
if (retval.0D.1698)
{
bad_rehash_sizeD.1697:;
foo ();
}
else
{
}
}
goto bad_rehash_sizeD.1697;
}
at which point the goto enters a scope with local objects constructed
before the jump target. Thus the FE generates a new scope around the
if statement where the temporary object is bound to and somehow this
is a of type sk_catch (that there is no checking whether something can
throw inside the block may be a problem).
With gcc 4.1 where the testcase is accepted we gimplify to
int main(int, char**) (argc, argv)
{
boolD.1451 retval.0D.1759;
struct objectD.1732 D.1760;
intD.2 D.1761;
intD.2 D.1762;
D.1760.one_oD.1734 = 7;
D.1760.allocstampD.1735 = 100;
D.1761 = pgci_pointable (D.1760);
retval.0D.1759 = D.1761 != 0;
if (retval.0D.1759)
{
bad_rehash_sizeD.1758:;
foo ();
}
else
{
}
goto bad_rehash_sizeD.1758;
not creating this extra scope.
--
rguenth at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
Keywords| |rejects-valid
Known to fail| |4.2.3 4.3.0
Known to work| |4.1.3
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35708