aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/class.c
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2003-03-16 14:36:43 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2003-03-16 14:36:43 +0000
commit1f5a253a36c2e680af7a627a5077a61fb8afe6b6 (patch)
tree7874404e7e5a23052c2153596208ca845cfa33ef /gcc/cp/class.c
parent46ea50cb66f3edc9f5f474067e61bfe39c41cb06 (diff)
downloadgcc-1f5a253a36c2e680af7a627a5077a61fb8afe6b6.zip
gcc-1f5a253a36c2e680af7a627a5077a61fb8afe6b6.tar.gz
gcc-1f5a253a36c2e680af7a627a5077a61fb8afe6b6.tar.bz2
re PR c++/9629 (virtual inheritance segfault)
cp: PR c++/9629 * cp-tree.h (struct language_function): Add in_base_initializer. (in_base_initializer): define it. (expand_member_init): Remove INIT param. * init.c (expand_member_init): Remove INIT param, return the member. (emit_mem_initializers): Set in_base_initializer. * class.c (build_base_path): Check in_base_initializer. * parser.c (cp_parser_mem_initializer): Set in_base_initializer. * pt.c (tsubst_initializer_list): Likewise. testsuite: PR c++/9629 * g++.dg/init/ctor2.C: New test. From-SVN: r64438
Diffstat (limited to 'gcc/cp/class.c')
-rw-r--r--gcc/cp/class.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 6b89bec..0df87ae 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -302,8 +302,25 @@ build_base_path (enum tree_code code,
/* Going via virtual base V_BINFO. We need the static offset
from V_BINFO to BINFO, and the dynamic offset from D_BINFO to
V_BINFO. That offset is an entry in D_BINFO's vtable. */
- tree v_offset = build_vfield_ref (build_indirect_ref (expr, NULL),
- TREE_TYPE (TREE_TYPE (expr)));
+ tree v_offset;
+
+ if (fixed_type_p < 0 && in_base_initializer)
+ {
+ /* In a base member initializer, we cannot rely on
+ the vtable being set up. We have to use the vtt_parm. */
+ tree derived = BINFO_INHERITANCE_CHAIN (v_binfo);
+
+ v_offset = build (PLUS_EXPR, TREE_TYPE (current_vtt_parm),
+ current_vtt_parm, BINFO_VPTR_INDEX (derived));
+
+ v_offset = build1 (INDIRECT_REF,
+ TREE_TYPE (TYPE_VFIELD (BINFO_TYPE (derived))),
+ v_offset);
+
+ }
+ else
+ v_offset = build_vfield_ref (build_indirect_ref (expr, NULL),
+ TREE_TYPE (TREE_TYPE (expr)));
v_offset = build (PLUS_EXPR, TREE_TYPE (v_offset),
v_offset, BINFO_VPTR_FIELD (v_binfo));