aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2002-04-16 18:52:38 -0700
committerRichard Henderson <rth@gcc.gnu.org>2002-04-16 18:52:38 -0700
commitff2c46ac2987d86c445b1d9ceb922822a22e86be (patch)
treec5ae4aa22955a383c3707fc61b8ad066906e115b
parentb2123dc0d8b3c18313c9aae7bddf57af0b4a6bf7 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/except.c42
-rw-r--r--gcc/testsuite/g++.dg/eh/dead1.C20
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 = &region->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;
+ }
+}