2004-10-07 Jakub Jelinek PR tree-optimization/17724 * tree-cfg.c (tree_purge_dead_eh_edges): Recompute dominator for the EH block. (remove_phi_nodes_and_edges_for_unreachab): Recompute dominators and post-dominators for predecessors and successors. * 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/tree-cfg.c 2004-10-02 11:19:53.042030301 +0200 +++ gcc/tree-cfg.c 2004-10-02 23:17:12.229321933 +0200 @@ -1784,6 +1784,8 @@ remove_phi_nodes_and_edges_for_unreachable_block (basic_block bb) { tree phi; + basic_block *succs = NULL; + int nsuccs = 0; /* Since this block is no longer reachable, we can just delete all of its PHI nodes. */ @@ -1795,9 +1797,32 @@ phi = next; } + if (dom_computed[CDI_DOMINATORS]) + succs = xmalloc (sizeof (basic_block *) * EDGE_COUNT (bb->succs)); + /* Remove edges to BB's successors. */ while (EDGE_COUNT (bb->succs) > 0) - ssa_remove_edge (EDGE_SUCC (bb, 0)); + { + if (succs != NULL + && EDGE_SUCC (bb, 0)->dest != bb + && EDGE_COUNT (EDGE_SUCC (bb, 0)->dest->preds) > 1) + succs[nsuccs++] = EDGE_SUCC (bb, 0)->dest; + ssa_remove_edge (EDGE_SUCC (bb, 0)); + } + + if (succs) + { + int i; + + for (i = 0; i < nsuccs; ++i) + { + basic_block dom = recount_dominator (CDI_DOMINATORS, succs[i]); + + if (dom != get_immediate_dominator (CDI_DOMINATORS, succs[i])) + set_immediate_dominator (CDI_DOMINATORS, succs[i], dom); + } + free (succs); + } } @@ -5089,7 +5114,12 @@ { 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; } +}