init.c (expand_aggr_vbase_init): Rename to construct_virtual_bases.
authorMark Mitchell <mark@codesourcery.com>
Tue, 22 Jun 1999 07:21:50 +0000 (07:21 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 22 Jun 1999 07:21:50 +0000 (07:21 +0000)
* init.c (expand_aggr_vbase_init): Rename to
construct_virtual_bases.  Conditionalize construction here,
rather than ...
(emit_base_init): Here.

From-SVN: r27701

gcc/cp/ChangeLog
gcc/cp/init.c
gcc/testsuite/g++.old-deja/g++.eh/vbase3.C [new file with mode: 0644]

index 9885a33a0b7f07236c27f98addfd95529f5f2c6e..d7eeea4a2d710706eb362aaf75e59ddced6b7a00 100644 (file)
@@ -1,3 +1,10 @@
+1999-06-21  Mark Mitchell  <mark@codesourcery.com>
+
+       * init.c (expand_aggr_vbase_init): Rename to
+       construct_virtual_bases.  Conditionalize construction here, 
+       rather than ...
+       (emit_base_init): Here.
+
 1999-06-19  Mark Mitchell  <mark@codesourcery.com>
 
        * semantics.c (finish_asm_statement): Apply decay conversions to
index db95fb5dba533bf079e7735f7bfa6c9e2ece93dd..cba2842fe6b47d03a276198117ca0be7b1c3881c 100644 (file)
@@ -44,7 +44,7 @@ Boston, MA 02111-1307, USA.  */
 tree current_base_init_list, current_member_init_list;
 
 static void expand_aggr_vbase_init_1 PROTO((tree, tree, tree, tree));
-static void expand_aggr_vbase_init PROTO((tree, tree, tree, tree, tree));
+static void construct_virtual_bases PROTO((tree, tree, tree, tree, tree));
 static void expand_aggr_init_1 PROTO((tree, tree, tree, tree, int));
 static void expand_default_init PROTO((tree, tree, tree, tree, int));
 static tree build_vec_delete_1 PROTO((tree, tree, tree, tree, tree,
@@ -541,14 +541,13 @@ emit_base_init (t, immediately)
   sort_base_init (t, &rbase_init_list, &vbase_init_list);
   current_base_init_list = NULL_TREE;
 
+  /* First, initialize the virtual base classes, if we are
+     constructing the most-derived object.  */
   if (TYPE_USES_VIRTUAL_BASECLASSES (t))
     {
       tree first_arg = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl));
-
-      expand_start_cond (first_arg, 0);
-      expand_aggr_vbase_init (t_binfo, current_class_ref, current_class_ptr,
-                             vbase_init_list, first_arg);
-      expand_end_cond ();
+      construct_virtual_bases (t, current_class_ref, current_class_ptr,
+                              vbase_init_list, first_arg);
     }
 
   /* Now, perform initialization of non-virtual base classes.  */
@@ -798,38 +797,60 @@ expand_aggr_vbase_init_1 (binfo, exp, addr, init_list)
   free_temp_slots ();
 }
 
-/* Initialize this object's virtual base class pointers.  This must be
-   done only at the top-level of the object being constructed.
-
-   INIT_LIST is list of initialization for constructor to perform.  */
+/* Construct the virtual base-classes of THIS_REF (whose address is
+   THIS_PTR).  The object has the indicated TYPE.  The construction
+   actually takes place only if FLAG is non-zero.  INIT_LIST is list
+   of initialization for constructor to perform.  */
 
 static void
-expand_aggr_vbase_init (binfo, exp, addr, init_list, flag)
-     tree binfo;
-     tree exp;
-     tree addr;
+construct_virtual_bases (type, this_ref, this_ptr, init_list, flag)
+     tree type;
+     tree this_ref;
+     tree this_ptr;
      tree init_list;
      tree flag;
 {
-  tree type = BINFO_TYPE (binfo);
+  tree vbases;
+  tree result;
 
-  if (TYPE_USES_VIRTUAL_BASECLASSES (type))
-    {
-      tree result = init_vbase_pointers (type, addr);
-      tree vbases;
+  /* If there are no virtual baseclasses, we shouldn't even be here.  */
+  my_friendly_assert (TYPE_USES_VIRTUAL_BASECLASSES (type), 19990621);
 
-      if (result)
-       expand_expr_stmt (build_compound_expr (result));
+  /* First set the pointers in our object that tell us where to find
+     our virtual baseclasses.  */
+  expand_start_cond (flag, 0);
+  result = init_vbase_pointers (type, this_ptr);
+  if (result)
+    expand_expr_stmt (build_compound_expr (result));
+  expand_end_cond ();
 
-      for (vbases = CLASSTYPE_VBASECLASSES (type); vbases;
-          vbases = TREE_CHAIN (vbases))
-       {
-         tree tmp = purpose_member (vbases, result);
-         expand_aggr_vbase_init_1 (vbases, exp,
-                                   TREE_OPERAND (TREE_VALUE (tmp), 0),
-                                   init_list);
-         expand_cleanup_for_base (vbases, flag);
-       }
+  /* Now, run through the baseclasses, initializing each.  */ 
+  for (vbases = CLASSTYPE_VBASECLASSES (type); vbases;
+       vbases = TREE_CHAIN (vbases))
+    {
+      tree tmp = purpose_member (vbases, result);
+      
+      /* If there are virtual base classes with destructors, we need to
+        emit cleanups to destroy them if an exception is thrown during
+        the construction process.  These exception regions (i.e., the
+        period during which the cleanups must occur) begin from the time
+        the construction is complete to the end of the function.  If we
+        create a conditional block in which to initialize the
+        base-classes, then the cleanup region for the virtual base begins
+        inside a block, and ends outside of that block.  This situation
+        confuses the sjlj exception-handling code.  Therefore, we do not
+        create a single conditional block, but one for each
+        initialization.  (That way the cleanup regions always begin
+        in the outer block.)  We trust the back-end to figure out
+        that the FLAG will not change across initializations, and
+        avoid doing multiple tests.  */
+      expand_start_cond (flag, 0);
+      expand_aggr_vbase_init_1 (vbases, this_ref,
+                               TREE_OPERAND (TREE_VALUE (tmp), 0),
+                               init_list);
+      expand_end_cond ();
+      
+      expand_cleanup_for_base (vbases, flag);
     }
 }
 
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/vbase3.C b/gcc/testsuite/g++.old-deja/g++.eh/vbase3.C
new file mode 100644 (file)
index 0000000..7cffa6c
--- /dev/null
@@ -0,0 +1,13 @@
+// Build don't link:
+// Special g++ Options: -fsjlj-exceptions
+// Origin: Donn Terry <donn@interix.com>
+
+struct ios {
+  virtual ~ios();
+};
+struct fstreambase : virtual public ios {
+  fstreambase();
+};
+fstreambase::fstreambase()
+{
+}