except.c (collect_one_action_chain): Add an explicit cleanup action if regions surrounding a catch were encoded...

* except.c (collect_one_action_chain): Add an explicit cleanup
        action if regions surrounding a catch were encoded entirely
        within the call-site entry.

        * g++.dg/eh/filter1.C, g++.dg/eh/filter2.C: New tests.

From-SVN: r44616
This commit is contained in:
Richard Henderson 2001-08-03 16:15:51 -07:00 committed by Richard Henderson
parent c99fa40fbe
commit 949f197fa6
5 changed files with 132 additions and 1 deletions

View file

@ -1,3 +1,9 @@
2001-08-03 Richard Henderson <rth@redhat.com>
* except.c (collect_one_action_chain): Add an explicit cleanup
action if regions surrounding a catch were encoded entirely
within the call-site entry.
2001-08-03 Richard Henderson <rth@redhat.com>
* dbxout.c (dbxout_symbol_location): Flatten subregs first;

View file

@ -3020,6 +3020,17 @@ expand_eh_return ()
emit_label (around_label);
}
/* In the following functions, we represent entries in the action table
as 1-based indicies. Special cases are:
0: null action record, non-null landing pad; implies cleanups
-1: null action record, null landing pad; implies no action
-2: no call-site entry; implies must_not_throw
-3: we have yet to process outer regions
Further, no special cases apply to the "next" field of the record.
For next, 0 means end of list. */
struct action_record
{
int offset;
@ -3123,8 +3134,16 @@ collect_one_action_chain (ar_hash, region)
if (next == -3)
{
next = collect_one_action_chain (ar_hash, region->outer);
if (next < 0)
/* If there is no next action, terminate the chain. */
if (next == -1)
next = 0;
/* If all outer actions are cleanups or must_not_throw,
we'll have no action record for it, since we had wanted
to encode these states in the call-site record directly.
Add a cleanup action to the chain to catch these. */
else if (next <= 0)
next = add_action_record (ar_hash, 0, 0);
}
next = add_action_record (ar_hash, c->u.catch.filter, next);
}

View file

@ -1,3 +1,7 @@
2001-08-03 Richard Henderson <rth@redhat.com>
* g++.dg/eh/filter1.C, g++.dg/eh/filter2.C: New tests.
2001-08-02 Neil Booth <neil@daikokuya.demon.co.uk>
* gcc.dg/cpp/19951025-1.c: Update.

View file

@ -0,0 +1,43 @@
// Test that cleanups get run when a catch filter fails to match.
// { dg-do run }
extern "C" void exit(int);
extern "C" void abort();
struct a
{
a();
~a();
};
struct e1 {};
struct e2 {};
void
ex_test ()
{
a aa;
try
{
throw e1 ();
}
catch (e2 &)
{
}
}
int
main ()
{
try
{
ex_test ();
}
catch (...)
{
}
abort ();
}
a::a() { }
a::~a() { exit (0); }

View file

@ -0,0 +1,59 @@
// Test that terminate gets run when a catch filter fails to match while
// running destructors. Original bug depended on a::~a being inlined.
// { dg-do run }
// { dg-options -O }
#include <exception>
#include <cstdlib>
struct e1 {};
struct e2 {};
struct a
{
a () { }
~a ()
{
try
{
throw e1();
}
catch (e2 &)
{
}
}
};
void
ex_test ()
{
a aa;
try
{
throw e1 ();
}
catch (e2 &)
{
}
}
void my_terminate ()
{
std::exit (0);
}
int
main ()
{
std::set_terminate (my_terminate);
try
{
ex_test ();
}
catch (...)
{
}
abort ();
}