init.c (expand_aggr_vbase_init): Add flag parameter.
authorMark Mitchell <mark@codesourcery.com>
Fri, 18 Jun 1999 20:35:56 +0000 (20:35 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Fri, 18 Jun 1999 20:35:56 +0000 (20:35 +0000)
* init.c (expand_aggr_vbase_init): Add flag parameter.
(build_partial_cleanup_for): Remove, inlining into ..
(expand_cleanup_for_base): ... here.  Take flag parameter.
(emit_base_init): Pass the in_chrg parameter to
emit_aggr_vbase_init.
(emit_aggr_vbase_init): Pass it to expand_cleanup_for_base.

From-SVN: r27600

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

index 1037548b7a2b56073abde2773ca785b568789b1e..b671eb324adbf923ffc514d5ec16e287a4895c96 100644 (file)
@@ -1,3 +1,12 @@
+1999-06-18  Mark Mitchell  <mark@codesourcery.com>
+
+       * init.c (expand_aggr_vbase_init): Add flag parameter.
+       (build_partial_cleanup_for): Remove, inlining into ..
+       (expand_cleanup_for_base): ... here.  Take flag parameter.
+       (emit_base_init): Pass the in_chrg parameter to
+       emit_aggr_vbase_init. 
+       (emit_aggr_vbase_init): Pass it to expand_cleanup_for_base.
+       
 1999-06-16  Mark Mitchell  <mark@codesourcery.com>
 
        * decl2.c (import_export_decl): Use same_type_p, rather than
index 019b5f9117757395a8ff3ff54b5a4b5f3a827f5e..db95fb5dba533bf079e7735f7bfa6c9e2ece93dd 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));
+static void expand_aggr_vbase_init 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,
@@ -55,12 +55,11 @@ static tree build_builtin_delete_call PROTO((tree));
 static int member_init_ok_or_else PROTO((tree, tree, const char *));
 static void expand_virtual_init PROTO((tree, tree));
 static tree sort_member_init PROTO((tree));
-static tree build_partial_cleanup_for PROTO((tree));
 static tree initializing_context PROTO((tree));
 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));
+static void expand_cleanup_for_base PROTO((tree, tree));
 
 /* Cache the identifier nodes for the magic field of a new cookie.  */
 static tree nc_nelts_field_id;
@@ -483,17 +482,6 @@ sort_base_init (t, rbase_ptr, vbase_ptr)
   *vbase_ptr = vbases;
 }
 
-/* Perform partial cleanups for a base for exception handling.  */
-
-static tree
-build_partial_cleanup_for (binfo)
-     tree binfo;
-{
-  return build_scoped_method_call
-    (current_class_ref, binfo, dtor_identifier,
-     build_expr_list (NULL_TREE, integer_zero_node));
-}
-
 /* Perform whatever initializations have yet to be done on the base
    class of the class variable.  These actions are in the global
    variable CURRENT_BASE_INIT_LIST.  Such an action could be
@@ -559,7 +547,7 @@ emit_base_init (t, immediately)
 
       expand_start_cond (first_arg, 0);
       expand_aggr_vbase_init (t_binfo, current_class_ref, current_class_ptr,
-                             vbase_init_list);
+                             vbase_init_list, first_arg);
       expand_end_cond ();
     }
 
@@ -598,7 +586,7 @@ emit_base_init (t, immediately)
          free_temp_slots ();
        }
 
-      expand_cleanup_for_base (base_binfo);
+      expand_cleanup_for_base (base_binfo, NULL_TREE);
       rbase_init_list = TREE_CHAIN (rbase_init_list);
     }
 
@@ -757,11 +745,14 @@ expand_virtual_init (binfo, decl)
 
 /* 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.  */
+   for BINFO, which has just been constructed.  If FLAG is non-NULL,
+   it is a DECL which is non-zero when this base needs to be
+   destroyed.  */
 
 static void
-expand_cleanup_for_base (binfo)
+expand_cleanup_for_base (binfo, flag)
      tree binfo;
+     tree flag;
 {
   tree expr;
 
@@ -771,7 +762,16 @@ expand_cleanup_for_base (binfo)
   /* All cleanups must be on the function_obstack.  */
   push_obstacks_nochange ();
   resume_temporary_allocation ();
-  expr = build_partial_cleanup_for (binfo);
+
+  /* Call the destructor.  */
+  expr = (build_scoped_method_call
+         (current_class_ref, binfo, dtor_identifier,
+          build_expr_list (NULL_TREE, integer_zero_node)));
+  if (flag)
+    expr = fold (build (COND_EXPR, void_type_node,
+                       truthvalue_conversion (flag),
+                       expr, integer_zero_node));
+
   pop_obstacks ();
   add_partial_entry (expr);
 }
@@ -804,11 +804,12 @@ expand_aggr_vbase_init_1 (binfo, exp, addr, init_list)
    INIT_LIST is list of initialization for constructor to perform.  */
 
 static void
-expand_aggr_vbase_init (binfo, exp, addr, init_list)
+expand_aggr_vbase_init (binfo, exp, addr, init_list, flag)
      tree binfo;
      tree exp;
      tree addr;
      tree init_list;
+     tree flag;
 {
   tree type = BINFO_TYPE (binfo);
 
@@ -827,7 +828,7 @@ expand_aggr_vbase_init (binfo, exp, addr, init_list)
          expand_aggr_vbase_init_1 (vbases, exp,
                                    TREE_OPERAND (TREE_VALUE (tmp), 0),
                                    init_list);
-         expand_cleanup_for_base (vbases);
+         expand_cleanup_for_base (vbases, flag);
        }
     }
 }
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/vbase2.C b/gcc/testsuite/g++.old-deja/g++.eh/vbase2.C
new file mode 100644 (file)
index 0000000..abf7223
--- /dev/null
@@ -0,0 +1,34 @@
+// Origin: Mark Mitchell <mark@codesourcery.com>
+
+int i;
+
+struct A
+{
+  A () { i++; }
+  ~A () { i--; }
+};
+
+struct B : public virtual A
+{
+  B () { throw 1; }
+};
+
+struct D: public B, virtual public A
+{
+};
+
+void f()
+{
+  D d;
+}
+
+int main ()
+{
+  try {
+    f();
+  } catch (int) {
+  }
+
+  return i;
+}
+