diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2003-03-16 14:36:43 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2003-03-16 14:36:43 +0000 |
commit | 1f5a253a36c2e680af7a627a5077a61fb8afe6b6 (patch) | |
tree | 7874404e7e5a23052c2153596208ca845cfa33ef /gcc/cp/class.c | |
parent | 46ea50cb66f3edc9f5f474067e61bfe39c41cb06 (diff) | |
download | gcc-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.c | 21 |
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)); |