diff options
author | Richard Henderson <rth@redhat.com> | 2002-04-16 18:52:38 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2002-04-16 18:52:38 -0700 |
commit | ff2c46ac2987d86c445b1d9ceb922822a22e86be (patch) | |
tree | c5ae4aa22955a383c3707fc61b8ad066906e115b | |
parent | b2123dc0d8b3c18313c9aae7bddf57af0b4a6bf7 (diff) | |
download | gcc-ff2c46ac2987d86c445b1d9ceb922822a22e86be.zip gcc-ff2c46ac2987d86c445b1d9ceb922822a22e86be.tar.gz gcc-ff2c46ac2987d86c445b1d9ceb922822a22e86be.tar.bz2 |
re PR c++/6320 (3.1 regression wrt 3.0: ICE in remove_eh_handler, at except.c:2696)
PR c++/6320
* except.c (remove_eh_handler): Insert inner regions at beginning
of sibling chain. Refactor expressions.
* g++.dg/eh/dead1.C: New.
From-SVN: r52397
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/except.c | 42 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/eh/dead1.C | 20 |
3 files changed, 48 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f846e68..9b1f9e1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2002-04-16 Richard Henderson <rth@redhat.com> + PR c++/6320 + * except.c (remove_eh_handler): Insert inner regions at beginning + of sibling chain. Refactor expressions. + +2002-04-16 Richard Henderson <rth@redhat.com> + * config/sparc/sol2-bi.h (AS_SPARC64_FLAG): New. * config/sparc/sol2-gas-bi.h: New file. * config.gcc (sparc*-solaris): Add it as needed. diff --git a/gcc/except.c b/gcc/except.c index e79d232..e1f32a5 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -2579,7 +2579,7 @@ static void remove_eh_handler (region) struct eh_region *region; { - struct eh_region **pp, *p; + struct eh_region **pp, **pp_start, *p, *outer, *inner; rtx lab; /* For the benefit of efficiently handling REG_EH_REGION notes, @@ -2588,21 +2588,22 @@ remove_eh_handler (region) multiple copies of this region in the array, so we have a list of alternate numbers by which we are known. */ - cfun->eh->region_array[region->region_number] = region->outer; + outer = region->outer; + cfun->eh->region_array[region->region_number] = outer; if (region->aka) { int i; EXECUTE_IF_SET_IN_BITMAP (region->aka, 0, i, - { cfun->eh->region_array[i] = region->outer; }); + { cfun->eh->region_array[i] = outer; }); } - if (region->outer) + if (outer) { - if (!region->outer->aka) - region->outer->aka = BITMAP_XMALLOC (); + if (!outer->aka) + outer->aka = BITMAP_XMALLOC (); if (region->aka) - bitmap_a_or_b (region->outer->aka, region->outer->aka, region->aka); - bitmap_set_bit (region->outer->aka, region->region_number); + bitmap_a_or_b (outer->aka, outer->aka, region->aka); + bitmap_set_bit (outer->aka, region->region_number); } if (cfun->eh->built_landing_pads) @@ -2612,23 +2613,24 @@ remove_eh_handler (region) if (lab) remove_exception_handler_label (lab); - if (region->outer) - pp = ®ion->outer->inner; + if (outer) + pp_start = &outer->inner; else - pp = &cfun->eh->region_tree; - for (p = *pp; p != region; pp = &p->next_peer, p = *pp) + pp_start = &cfun->eh->region_tree; + for (pp = pp_start, p = *pp; p != region; pp = &p->next_peer, p = *pp) continue; + *pp = region->next_peer; - if (region->inner) + inner = region->inner; + if (inner) { - for (p = region->inner; p->next_peer ; p = p->next_peer) - p->outer = region->outer; - p->next_peer = region->next_peer; - p->outer = region->outer; - *pp = region->inner; + for (p = inner; p->next_peer ; p = p->next_peer) + p->outer = outer; + p->outer = outer; + + p->next_peer = *pp_start; + *pp_start = inner; } - else - *pp = region->next_peer; if (region->type == ERT_CATCH) { diff --git a/gcc/testsuite/g++.dg/eh/dead1.C b/gcc/testsuite/g++.dg/eh/dead1.C new file mode 100644 index 0000000..88ae922 --- /dev/null +++ b/gcc/testsuite/g++.dg/eh/dead1.C @@ -0,0 +1,20 @@ +// PR 6320 +// Rechained the MUST_NOT_THROW region in the wrong order wrt the +// TRY/CATCH while removing them and got confused. +// { dg-do compile } + +struct S { + ~S(); +}; + +void foo() +{ + try { + return; + } + catch (int) { + } + catch (...) { + S s; + } +} |