From d7f63cfa154c4c96a01dec9d8ba59db5d1ca085c Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 6 Mar 2014 08:54:28 +0100 Subject: [PATCH] backport: re PR middle-end/57499 (ICE when noreturn destructor returns after throw with -O) Backport from mainline 2014-02-05 Jakub Jelinek PR middle-end/57499 * tree-eh.c (cleanup_empty_eh): Bail out on totally empty bb with no successors. * g++.dg/torture/pr57499.C: New test. From-SVN: r208363 --- gcc/ChangeLog | 9 +++++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/torture/pr57499.C | 14 ++++++++++++++ gcc/tree-eh.c | 7 +++++-- 4 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr57499.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f0b9daab896e..347cf1f8537d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2014-03-06 Jakub Jelinek + + Backport from mainline + 2014-02-05 Jakub Jelinek + + PR middle-end/57499 + * tree-eh.c (cleanup_empty_eh): Bail out on totally empty + bb with no successors. + 2014-03-04 Richard Biener PR tree-optimization/60382 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a86397f2e1a7..85648af403a2 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,11 @@ 2014-03-06 Jakub Jelinek Backport from mainline + 2014-02-05 Jakub Jelinek + + PR middle-end/57499 + * g++.dg/torture/pr57499.C: New test. + 2014-03-03 Jakub Jelinek PR preprocessor/60400 diff --git a/gcc/testsuite/g++.dg/torture/pr57499.C b/gcc/testsuite/g++.dg/torture/pr57499.C new file mode 100644 index 000000000000..fd985a199b84 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr57499.C @@ -0,0 +1,14 @@ +// PR middle-end/57499 +// { dg-do compile } + +struct S +{ + ~S () __attribute__ ((noreturn)) {} // { dg-warning "function does return" } +}; + +void +foo () +{ + S s; + throw 1; +} diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 87fea6d07cfb..902ce452791c 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -4184,8 +4184,11 @@ cleanup_empty_eh (eh_landing_pad lp) /* If the block is totally empty, look for more unsplitting cases. */ if (gsi_end_p (gsi)) { - /* For the degenerate case of an infinite loop bail out. */ - if (infinite_empty_loop_p (e_out)) + /* For the degenerate case of an infinite loop bail out. + If bb has no successors and is totally empty, which can happen e.g. + because of incorrect noreturn attribute, bail out too. */ + if (e_out == NULL + || infinite_empty_loop_p (e_out)) return ret; return ret | cleanup_empty_eh_unsplit (bb, e_out, lp); -- 2.47.2