aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/init.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-10-13 14:01:51 -0400
committerJason Merrill <jason@gcc.gnu.org>2011-10-13 14:01:51 -0400
commit1fb0b80148f60850b5e2595d5e125cb826eafd6c (patch)
treed27698a7e57e68696f93b4980066a65a55938d99 /gcc/cp/init.c
parent40746f4023a9b064cf703cc722d50a8996b2837b (diff)
downloadgcc-1fb0b80148f60850b5e2595d5e125cb826eafd6c.zip
gcc-1fb0b80148f60850b5e2595d5e125cb826eafd6c.tar.gz
gcc-1fb0b80148f60850b5e2595d5e125cb826eafd6c.tar.bz2
re PR c++/50618 (Virtual inheritance segfault)
PR c++/50618 * init.c (expand_aggr_init_1): Don't zero-initialize virtual bases of a base subobject. From-SVN: r179934
Diffstat (limited to 'gcc/cp/init.c')
-rw-r--r--gcc/cp/init.c32
1 files changed, 15 insertions, 17 deletions
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 7897fff..a21e566 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1588,27 +1588,25 @@ expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags,
that's value-initialization. */
if (init == void_type_node)
{
- /* If there's a user-provided constructor, we just call that. */
- if (type_has_user_provided_constructor (type))
- /* Fall through. */;
- /* If there isn't, but we still need to call the constructor,
- zero out the object first. */
- else if (type_build_ctor_call (type))
- {
- init = build_zero_init (type, NULL_TREE, /*static_storage_p=*/false);
+ /* If no user-provided ctor, we need to zero out the object. */
+ if (!type_has_user_provided_constructor (type))
+ {
+ tree field_size = NULL_TREE;
+ if (exp != true_exp && CLASSTYPE_AS_BASE (type) != type)
+ /* Don't clobber already initialized virtual bases. */
+ field_size = TYPE_SIZE (CLASSTYPE_AS_BASE (type));
+ init = build_zero_init_1 (type, NULL_TREE, /*static_storage_p=*/false,
+ field_size);
init = build2 (INIT_EXPR, type, exp, init);
finish_expr_stmt (init);
- /* And then call the constructor. */
}
+
/* If we don't need to mess with the constructor at all,
- then just zero out the object and we're done. */
- else
- {
- init = build2 (INIT_EXPR, type, exp,
- build_value_init_noctor (type, complain));
- finish_expr_stmt (init);
- return;
- }
+ then we're done. */
+ if (! type_build_ctor_call (type))
+ return;
+
+ /* Otherwise fall through and call the constructor. */
init = NULL_TREE;
}