2004-10-07 Jakub Jelinek PR tree-optimization/17724 * tree-cfg.c (tree_purge_dead_eh_edges): Recompute dominator for the EH block. (cleanup_tree_cfg): Remove unnecessary retval initialization. * cfgcleanup.c (delete_unreachable_blocks): Recompute dominators and post-dominators for predecessors and successors of deleted unreachable basic blocks. * g++.dg/opt/pr17724-1.C: New test. * g++.dg/opt/pr17724-2.C: New test. * g++.dg/opt/pr17724-3.C: New test. * g++.dg/opt/pr17724-4.C: New test. * g++.dg/opt/pr17724-5.C: New test. * g++.dg/opt/pr17724-6.C: New test. --- gcc/cfgcleanup.c.jj 2004-09-28 04:19:43.000000000 -0400 +++ gcc/cfgcleanup.c 2004-10-07 12:30:11.000000000 -0400 @@ -2029,9 +2029,18 @@ delete_unreachable_blocks (void) { bool changed = false; basic_block b, next_bb; + basic_block *succs = NULL, *preds = NULL; + int nsuccs = 0, npreds = 0, i; + edge_iterator ei; + edge e; find_unreachable_blocks (); + if (dom_computed[CDI_DOMINATORS]) + succs = xmalloc (sizeof (basic_block *) * n_basic_blocks); + if (dom_computed[CDI_POST_DOMINATORS]) + preds = xmalloc (sizeof (basic_block *) * n_basic_blocks); + /* Delete all unreachable basic blocks. */ for (b = ENTRY_BLOCK_PTR->next_bb; b != EXIT_BLOCK_PTR; b = next_bb) @@ -2040,6 +2049,22 @@ delete_unreachable_blocks (void) if (!(b->flags & BB_REACHABLE)) { + if (succs) + FOR_EACH_EDGE (e, ei, b->succs) + if ((e->dest->flags & (BB_REACHABLE | BB_VISITED)) + == BB_REACHABLE) + { + succs[nsuccs++] = e->dest; + e->dest->flags |= BB_VISITED; + } + if (preds) + FOR_EACH_EDGE (e, ei, b->preds) + if ((e->src->flags & (BB_REACHABLE | BB_VISITED)) + == BB_REACHABLE) + { + preds[npreds++] = e->src; + e->src->flags |= BB_VISITED; + } delete_basic_block (b); changed = true; } @@ -2047,6 +2072,33 @@ delete_unreachable_blocks (void) if (changed) tidy_fallthru_edges (); + + if (succs) + { + for (i = 0; i < nsuccs; ++i) + { + basic_block dom = recount_dominator (CDI_DOMINATORS, succs[i]); + + succs[i]->flags &= ~BB_VISITED; + if (dom != get_immediate_dominator (CDI_DOMINATORS, succs[i])) + set_immediate_dominator (CDI_DOMINATORS, succs[i], dom); + } + free (succs); + } + + if (preds) + { + for (i = 0; i < npreds; ++i) + { + basic_block dom = recount_dominator (CDI_POST_DOMINATORS, preds[i]); + + preds[i]->flags &= ~BB_VISITED; + if (dom != get_immediate_dominator (CDI_POST_DOMINATORS, preds[i])) + set_immediate_dominator (CDI_POST_DOMINATORS, preds[i], dom); + } + free (preds); + } + return changed; } --- gcc/tree-cfg.c.jj 2004-10-02 04:46:07.000000000 -0400 +++ gcc/tree-cfg.c 2004-10-07 12:28:44.000000000 -0400 @@ -5089,7 +5089,12 @@ tree_purge_dead_eh_edges (basic_block bb { if (e->flags & EDGE_EH) { + basic_block dest = e->dest, dom; + ssa_remove_edge (e); + dom = recount_dominator (CDI_DOMINATORS, dest); + if (dom != get_immediate_dominator (CDI_DOMINATORS, dest)) + set_immediate_dominator (CDI_DOMINATORS, dest, dom); changed = true; } else --- gcc/testsuite/g++.dg/opt/pr17724-4.C.jj 2004-10-02 11:27:29.000000000 +0200 +++ gcc/testsuite/g++.dg/opt/pr17724-4.C 2004-10-02 11:29:21.803990546 +0200 @@ -0,0 +1,24 @@ +// PR tree-optimization/17724 +// { dg-do compile } +// { dg-options "-O2" } + +extern "C" char *strcpy (char* d, const char* s); + +class A { public: A (); ~A (); }; + +inline char * B (char *s, const char *t) +{ return ::strcpy (s, t); } + +class C { int D (void); int E; }; + +int C::D (void) +{ + A a; + try + { + char z[22]; + if (this->E) B (z, ""); + return 0; + } + catch (int &f) { return -1; } +} --- gcc/testsuite/g++.dg/opt/pr17724-6.C.jj 2004-10-02 11:27:29.000000000 +0200 +++ gcc/testsuite/g++.dg/opt/pr17724-6.C 2004-10-02 11:28:39.000000000 +0200 @@ -0,0 +1,24 @@ +// PR tree-optimization/17724 +// { dg-do compile } +// { dg-options "-O2" } + +extern char *strcpy (char* d, const char* s); + +class A { public: A (); ~A (); }; + +inline char * B (char *s, const char *t) +{ return ::strcpy (s, t); } + +class C { int D (void); int E; }; + +int C::D (void) +{ + A a; + try + { + char z[22]; + if (this->E) B (z, ""); + return 0; + } + catch (int &f) { return -1; } +} --- gcc/testsuite/g++.dg/opt/pr17724-1.C.jj 2004-10-02 11:13:45.797278812 +0200 +++ gcc/testsuite/g++.dg/opt/pr17724-1.C 2004-10-02 11:13:45.797278812 +0200 @@ -0,0 +1,23 @@ +// PR tree-optimization/17724 +// { dg-do compile } +// { dg-options "-O2" } + +namespace N { char *strcpy (char *, const char *); } +extern "C" char *strcpy (char *, const char *) throw (); +inline char *N::strcpy (char *s, const char *t) { return ::strcpy (s, t); } + +struct S { ~S (); }; +int foo (); + +int +main () +{ + S s; + int a; + char b[64]; + N::strcpy (b, "ABCDEFGHIJKLM"); + while ((a = foo ()) != -1) + if (a) + return -1; + return 0; +} --- gcc/testsuite/g++.dg/opt/pr17724-2.C.jj 2004-10-02 11:13:45.797278812 +0200 +++ gcc/testsuite/g++.dg/opt/pr17724-2.C 2004-10-02 11:13:45.797278812 +0200 @@ -0,0 +1,23 @@ +// PR tree-optimization/17724 +// { dg-do compile } +// { dg-options "-O2" } + +namespace N { char *strcpy (char *, const char *); } +extern "C" char *strcpy (char *, const char *); +inline char *N::strcpy (char *s, const char *t) { return ::strcpy (s, t); } + +struct S { ~S (); }; +int foo (); + +int +main () +{ + S s; + int a; + char b[64]; + N::strcpy (b, "ABCDEFGHIJKLM"); + while ((a = foo ()) != -1) + if (a) + return -1; + return 0; +} --- gcc/testsuite/g++.dg/opt/pr17724-3.C.jj 2004-10-02 11:27:29.650919752 +0200 +++ gcc/testsuite/g++.dg/opt/pr17724-3.C 2004-10-02 11:29:13.933389195 +0200 @@ -0,0 +1,24 @@ +// PR tree-optimization/17724 +// { dg-do compile } +// { dg-options "-O2" } + +extern "C" char *strcpy (char* d, const char* s) throw (); + +class A { public: A (); ~A (); }; + +inline char * B (char *s, const char *t) +{ return ::strcpy (s, t); } + +class C { int D (void); int E; }; + +int C::D (void) +{ + A a; + try + { + char z[22]; + if (this->E) B (z, ""); + return 0; + } + catch (int &f) { return -1; } +} --- gcc/testsuite/g++.dg/opt/pr17724-5.C.jj 2004-10-02 11:27:29.000000000 +0200 +++ gcc/testsuite/g++.dg/opt/pr17724-5.C 2004-10-02 11:29:29.275662780 +0200 @@ -0,0 +1,24 @@ +// PR tree-optimization/17724 +// { dg-do compile } +// { dg-options "-O2" } + +extern char *strcpy (char* d, const char* s) throw (); + +class A { public: A (); ~A (); }; + +inline char * B (char *s, const char *t) +{ return ::strcpy (s, t); } + +class C { int D (void); int E; }; + +int C::D (void) +{ + A a; + try + { + char z[22]; + if (this->E) B (z, ""); + return 0; + } + catch (int &f) { return -1; } +}