This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[3.3/3.4/head] fix 14535
- From: Richard Henderson <rth at twiddle dot net>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 15 Mar 2004 16:33:46 -0800
- Subject: [3.3/3.4/head] fix 14535
Basically, we failed to record the existance of a cleanup in the
unwind info, so we never invoked it at runtime.
Applied mainline. Ok for 3.3/3.4?
r~
* except.c (collect_one_action_chain): Create action record for
cleanup outer of exception spec.
Index: except.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/except.c,v
retrieving revision 1.264
diff -u -p -r1.264 except.c
--- except.c 14 Mar 2004 22:26:04 -0000 1.264
+++ except.c 16 Mar 2004 00:29:47 -0000
@@ -3365,8 +3365,18 @@ collect_one_action_chain (htab_t ar_hash
/* 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
Index: testsuite/g++.dg/eh/spec7.C
===================================================================
RCS file: testsuite/g++.dg/eh/spec7.C
diff -N testsuite/g++.dg/eh/spec7.C
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/g++.dg/eh/spec7.C 16 Mar 2004 00:29:47 -0000
@@ -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 ();
+}