diff options
author | Jason Merrill <jason@redhat.com> | 2011-10-13 14:01:51 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2011-10-13 14:01:51 -0400 |
commit | 1fb0b80148f60850b5e2595d5e125cb826eafd6c (patch) | |
tree | d27698a7e57e68696f93b4980066a65a55938d99 | |
parent | 40746f4023a9b064cf703cc722d50a8996b2837b (diff) | |
download | gcc-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
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/init.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/vbase1.C | 39 |
4 files changed, 65 insertions, 17 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e7c5b49..e70f5c8 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2011-10-13 Jason Merrill <jason@redhat.com> + + PR c++/50618 + * init.c (expand_aggr_init_1): Don't zero-initialize virtual + bases of a base subobject. + 2011-10-12 Paolo Carlini <paolo.carlini@oracle.com> PR c++/50594 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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9f06ab4..283b699 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-10-13 Jason Merrill <jason@redhat.com> + + PR c++/50618 + * g++.dg/init/vbase1.C: New. + 2011-10-13 Jakub Jelinek <jakub@redhat.com> * gcc.target/i386/sse4_1-phminposuw-2.c: New test. diff --git a/gcc/testsuite/g++.dg/init/vbase1.C b/gcc/testsuite/g++.dg/init/vbase1.C new file mode 100644 index 0000000..bbfd58f --- /dev/null +++ b/gcc/testsuite/g++.dg/init/vbase1.C @@ -0,0 +1,39 @@ +// PR c++/50618 +// { dg-do run } + +struct Base +{ + const int text; + Base():text(1) {} + Base(int aText) + : text(aText) {} +}; +struct SubA : public virtual Base +{ +protected: + int x; +public: + SubA(int aX) + : x(aX) {} +}; +class SubB : public virtual Base +{}; +struct Diamond : public SubA, public SubB +{ + Diamond(int text) + : Base(text), SubA(5), SubB() {} + + void printText() + { + if(text != 2) + __builtin_abort(); + if(x!=5) + __builtin_abort(); + } +}; + +int main(int, char**) +{ + Diamond x(2); + x.printText(); +} |