summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>1999-06-22 07:21:50 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>1999-06-22 07:21:50 +0000
commit82b0688366a2dc83ce50838a9beaa22bc371a250 (patch)
treecaf1a3e11146b0f4b09a305822e174a85bc9f096 /gcc
parent688d5631e5872930dd5e26c1b5c228c400f7b0eb (diff)
downloadgcc-82b0688366a2dc83ce50838a9beaa22bc371a250.tar.gz
* init.c (expand_aggr_vbase_init): Rename to
construct_virtual_bases. Conditionalize construction here, rather than ... (emit_base_init): Here. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@27701 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/init.c81
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/vbase3.C13
3 files changed, 71 insertions, 30 deletions
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 <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
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 <donn@interix.com>
+
+struct ios {
+ virtual ~ios();
+};
+struct fstreambase : virtual public ios {
+ fstreambase();
+};
+fstreambase::fstreambase()
+{
+}