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): Free dominators if any delete_unreachable_blocks deleted some basic block. * 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.jj 2004-10-02 10:46:07.000000000 +0200 +++ gcc/tree-cfg.c 2004-10-02 11:19:53.042030301 +0200 @@ -713,11 +713,13 @@ bool cleanup_tree_cfg (void) { - bool retval = false; + bool retval; + bool blocks_deleted; timevar_push (TV_TREE_CLEANUP_CFG); retval = cleanup_control_flow (); - retval |= delete_unreachable_blocks (); + blocks_deleted = delete_unreachable_blocks (); + retval |= blocks_deleted; /* thread_jumps() sometimes leaves further transformation opportunities for itself, so iterate on it until nothing @@ -743,6 +745,13 @@ cleanup_tree_cfg (void) } #endif + /* If blocks were deleted, the dominance info might be outdated. */ + if (blocks_deleted) + { + free_dominance_info (CDI_DOMINATORS); + free_dominance_info (CDI_POST_DOMINATORS); + } + /* Merging the blocks creates no new opportunities for the other optimizations, so do it here. */ merge_seq_blocks (); @@ -5089,7 +5098,11 @@ 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); + 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; } +}