Message ID | 20140205123301.GA12671@tucnak.redhat.com |
---|---|
State | New |
Headers | show |
On Wed, 5 Feb 2014, Jakub Jelinek wrote: > Hi! > > As the testcase shows, invalid use of noreturn attribute (which we diagnose) > can result in in empty bb with no successors. This patch fixes > cleanup_empty_eh not to ICE on these. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? Ok. Thanks, Richard. > 2014-02-04 Jakub Jelinek <jakub@redhat.com> > > 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. > > --- gcc/tree-eh.c.jj 2014-01-31 22:22:09.000000000 +0100 > +++ gcc/tree-eh.c 2014-02-04 12:35:05.611066852 +0100 > @@ -4396,8 +4396,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); > --- gcc/testsuite/g++.dg/torture/pr57499.C.jj 2014-02-04 12:52:10.241846755 +0100 > +++ gcc/testsuite/g++.dg/torture/pr57499.C 2014-02-04 12:51:51.000000000 +0100 > @@ -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; > +} > > Jakub > >
--- gcc/tree-eh.c.jj 2014-01-31 22:22:09.000000000 +0100 +++ gcc/tree-eh.c 2014-02-04 12:35:05.611066852 +0100 @@ -4396,8 +4396,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); --- gcc/testsuite/g++.dg/torture/pr57499.C.jj 2014-02-04 12:52:10.241846755 +0100 +++ gcc/testsuite/g++.dg/torture/pr57499.C 2014-02-04 12:51:51.000000000 +0100 @@ -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; +}