From 69f00f0151543845d1ac41ecf8cf3609691890c1 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Tue, 22 Jun 1999 07:21:50 +0000 Subject: [PATCH] init.c (expand_aggr_vbase_init): Rename to construct_virtual_bases. * 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 | 7 ++ gcc/cp/init.c | 81 ++++++++++++++-------- gcc/testsuite/g++.old-deja/g++.eh/vbase3.C | 13 ++++ 3 files changed, 71 insertions(+), 30 deletions(-) create mode 100644 gcc/testsuite/g++.old-deja/g++.eh/vbase3.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9885a33a0b7..d7eeea4a2d7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +1999-06-21 Mark Mitchell + + * 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 * semantics.c (finish_asm_statement): Apply decay conversions to diff --git a/gcc/cp/init.c b/gcc/cp/init.c index db95fb5dba5..cba2842fe6b 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, 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 index 00000000000..7cffa6c0cb0 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.eh/vbase3.C @@ -0,0 +1,13 @@ +// Build don't link: +// Special g++ Options: -fsjlj-exceptions +// Origin: Donn Terry + +struct ios { + virtual ~ios(); +}; +struct fstreambase : virtual public ios { + fstreambase(); +}; +fstreambase::fstreambase() +{ +} -- 2.30.2