This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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 (); 
+} 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]