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]

C++ PATCH for vbase destruction



We failed to destroy virtual base classes when a derived class
constructor threw an exception.  (This is one of Martin's highlighted
bugs.)  

Installed on both the mainline and the branch.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

1999-06-16  Mark Mitchell  <mark@codesourcery.com>

	* init.c (expand_cleanup_for_base): New function, split out
	from ...
	(emit_base_init): Here.
	(expand_aggr_vbase_init): Use it.
	
Index: testsuite/g++.old-deja/g++.eh/vbase1.C
===================================================================
RCS file: vbase1.C
diff -N vbase1.C
--- /dev/null	Sat Dec  5 20:30:03 1998
+++ vbase1.C	Wed Jun 16 09:24:16 1999
@@ -0,0 +1,24 @@
+// Origin: Mark Mitchell <mark@codesourcery.com>
+
+int i;
+int j;
+
+struct B
+{
+  B() { i = 1; }
+  ~B() { j = 7; }
+};
+
+struct D : virtual public B {
+  D () { throw 3; }
+};
+
+int main ()
+{
+  try {
+    D d;
+  } catch (int) {
+    if (i != 1 || j != 7)
+      return 1;
+  }
+}
Index: cp/init.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/init.c,v
retrieving revision 1.107
diff -u -p -r1.107 init.c
--- init.c	1999/06/13 01:17:12	1.107
+++ init.c	1999/06/16 16:24:19
@@ -60,6 +60,7 @@ static tree initializing_context PROTO((
 static void expand_vec_init_try_block PROTO((tree));
 static void expand_vec_init_catch_clause PROTO((tree, tree, tree, tree));
 static tree build_java_class_ref PROTO((tree));
+static void expand_cleanup_for_base PROTO((tree));
 
 /* Cache the identifier nodes for the magic field of a new cookie.  */
 static tree nc_nelts_field_id;
@@ -597,18 +598,7 @@ emit_base_init (t, immediately)
 	  free_temp_slots ();
 	}
 
-      if (TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo)))
-	{
-	  tree expr;
-
-	  /* All cleanups must be on the function_obstack.  */
-	  push_obstacks_nochange ();
-	  resume_temporary_allocation ();
-	  expr = build_partial_cleanup_for (base_binfo);
-	  pop_obstacks ();
-	  add_partial_entry (expr);
-	}
-
+      expand_cleanup_for_base (base_binfo);
       rbase_init_list = TREE_CHAIN (rbase_init_list);
     }
 
@@ -765,6 +755,27 @@ expand_virtual_init (binfo, decl)
   expand_expr_stmt (build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl));
 }
 
+/* If an exception is thrown in a constructor, those base classes already
+   constructed must be destroyed.  This function creates the cleanup
+   for BINFO, which has just been constructed.  */
+
+static void
+expand_cleanup_for_base (binfo)
+     tree binfo;
+{
+  tree expr;
+
+  if (!TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (binfo)))
+    return;
+
+  /* All cleanups must be on the function_obstack.  */
+  push_obstacks_nochange ();
+  resume_temporary_allocation ();
+  expr = build_partial_cleanup_for (binfo);
+  pop_obstacks ();
+  add_partial_entry (expr);
+}
+
 /* Subroutine of `expand_aggr_vbase_init'.
    BINFO is the binfo of the type that is being initialized.
    INIT_LIST is the list of initializers for the virtual baseclass.  */
@@ -816,6 +827,7 @@ expand_aggr_vbase_init (binfo, exp, addr
 	  expand_aggr_vbase_init_1 (vbases, exp,
 				    TREE_OPERAND (TREE_VALUE (tmp), 0),
 				    init_list);
+	  expand_cleanup_for_base (vbases);
 	}
     }
 }


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