aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>1999-06-18 20:35:56 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1999-06-18 20:35:56 +0000
commit0b8a1e58d95a80ce908f20a5337080106dd74385 (patch)
tree7461d727c81de1730f1caff29fec1d7653a608db
parent34cea4e94fd267c3545d176443ad6718d5fac4d8 (diff)
downloadgcc-0b8a1e58d95a80ce908f20a5337080106dd74385.zip
gcc-0b8a1e58d95a80ce908f20a5337080106dd74385.tar.gz
gcc-0b8a1e58d95a80ce908f20a5337080106dd74385.tar.bz2
init.c (expand_aggr_vbase_init): Add flag parameter.
* 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
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/init.c43
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/vbase2.C34
3 files changed, 65 insertions, 21 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1037548..b671eb3 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 019b5f9..db95fb5 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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
index 0000000..abf7223
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.eh/vbase2.C
@@ -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;
+}
+