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:
parent
199f5c2b84
commit
0977ab3aa6
@ -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):
|
||||
|
14
gcc/except.c
14
gcc/except.c
@ -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
|
||||
|
35
gcc/testsuite/g++.dg/eh/spec7.C
Normal file
35
gcc/testsuite/g++.dg/eh/spec7.C
Normal 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 ();
|
||||
}
|
Loading…
Reference in New Issue
Block a user