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:
parent
c99fa40fbe
commit
949f197fa6
5 changed files with 132 additions and 1 deletions
|
@ -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;
|
||||
|
|
21
gcc/except.c
21
gcc/except.c
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
43
gcc/testsuite/g++.dg/eh/filter1.C
Normal file
43
gcc/testsuite/g++.dg/eh/filter1.C
Normal 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); }
|
59
gcc/testsuite/g++.dg/eh/filter2.C
Normal file
59
gcc/testsuite/g++.dg/eh/filter2.C
Normal 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 ();
|
||||
}
|
Loading…
Add table
Reference in a new issue