re PR middle-end/14535 (exception throwing in virtual function doesn't turn on the local destructors)

PR middle-end/14535
        * except.c (collect_one_action_chain): Record action for cleanup
        outer of exception spec.
	* g++.dg/eh/spec7.C: New.

From-SVN: r79521
This commit is contained in:
Richard Henderson 2004-03-15 16:35:17 -08:00 committed by Richard Henderson
parent 199f5c2b84
commit 0977ab3aa6
3 changed files with 53 additions and 2 deletions

View File

@ -1,3 +1,9 @@
2004-03-15 Richard Henderson <rth@redhat.com>
PR middle-end/14535
* except.c (collect_one_action_chain): Record action for cleanup
outer of exception spec.
2004-03-15 Ian Lance Taylor <ian@wasabisystems.com>
* config/rs6000/host-darwin.c (darwin_rs6000_gt_pch_use_address):

View File

@ -3365,8 +3365,18 @@ collect_one_action_chain (htab_t ar_hash, struct eh_region *region)
/* An exception specification adds its filter to the
beginning of the chain. */
next = collect_one_action_chain (ar_hash, region->outer);
return add_action_record (ar_hash, region->u.allowed.filter,
next < 0 ? 0 : next);
/* 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);
return add_action_record (ar_hash, region->u.allowed.filter, next);
case ERT_MUST_NOT_THROW:
/* A must-not-throw region with no inner handlers or cleanups

View File

@ -0,0 +1,35 @@
// PR 14535
// { dg-do run }
// { dg-options "-O -finline" }
//
// Original test case failure required that Raiser constructor be inlined.
extern "C" void abort();
bool destructor_called = false;
struct B {
virtual void Run(){};
};
struct D : public B {
virtual void Run()
{
struct O {
~O() { destructor_called = true; };
} o;
struct Raiser {
Raiser() throw( int ) {throw 1;};
} raiser;
};
};
int main() {
try {
D d;
static_cast<B&>(d).Run();
} catch (...) {}
if (!destructor_called)
abort ();
}