------- 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