diff options
author | Jason Merrill <jason@redhat.com> | 2009-02-11 17:38:37 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2009-02-11 17:38:37 -0500 |
commit | fd97a96a1049407b248f9e6927f6021ba0e02115 (patch) | |
tree | dc134d4d594d3c5e37ab4a52debdc05c7516eaf9 /gcc/cp | |
parent | 3ad6b2669b7a6d9cd1b12330fd7accd44fdd2154 (diff) | |
download | gcc-fd97a96a1049407b248f9e6927f6021ba0e02115.zip gcc-fd97a96a1049407b248f9e6927f6021ba0e02115.tar.gz gcc-fd97a96a1049407b248f9e6927f6021ba0e02115.tar.bz2 |
re PR c++/30111 (Value-initialization of POD base class doesn't initialize members)
PR c++/30111
* init.c (build_value_init_noctor): Split out from...
(build_value_init): ...here.
(expand_aggr_init_1): Handle value-initialization.
* cp-tree.h: Add declaration.
* class.c (type_has_user_provided_constructor):
Handle non-class arguments.
From-SVN: r144112
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/cp/class.c | 3 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/init.c | 48 |
4 files changed, 56 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 513465d..58bffd7 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2009-02-11 Jason Merrill <jason@redhat.com> + + PR c++/30111 + * init.c (build_value_init_noctor): Split out from... + (build_value_init): ...here. + (expand_aggr_init_1): Handle value-initialization. + * cp-tree.h: Add declaration. + * class.c (type_has_user_provided_constructor): + Handle non-class arguments. + 2009-02-10 Jason Merrill <jason@redhat.com> PR c++/38649 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index d852acd..cef2371 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -4090,6 +4090,9 @@ type_has_user_provided_constructor (tree t) { tree fns; + if (!CLASS_TYPE_P (t)) + return false; + if (!TYPE_HAS_USER_CONSTRUCTOR (t)) return false; diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 5bf8595..5a9b891 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4476,6 +4476,7 @@ extern int is_class_type (tree, int); extern tree get_type_value (tree); extern tree build_zero_init (tree, tree, bool); extern tree build_value_init (tree); +extern tree build_value_init_noctor (tree); extern tree build_offset_ref (tree, tree, bool); extern tree build_new (tree, tree, tree, tree, int, tsubst_flags_t); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index d4dafed..d583e3b 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -318,7 +318,21 @@ build_value_init (tree type) AGGR_INIT_ZERO_FIRST (ctor) = 1; return ctor; } - else if (TREE_CODE (type) != UNION_TYPE) + } + return build_value_init_noctor (type); +} + +/* Like build_value_init, but don't call the constructor for TYPE. Used + for base initializers. */ + +tree +build_value_init_noctor (tree type) +{ + if (CLASS_TYPE_P (type)) + { + gcc_assert (!TYPE_NEEDS_CONSTRUCTING (type)); + + if (TREE_CODE (type) != UNION_TYPE) { tree field; VEC(constructor_elt,gc) *v = NULL; @@ -800,11 +814,6 @@ emit_mem_initializers (tree mem_inits) "copy constructor", current_function_decl, BINFO_TYPE (subobject)); - /* If an explicit -- but empty -- initializer list was present, - treat it just like default initialization at this point. */ - if (arguments == void_type_node) - arguments = NULL_TREE; - /* Initialize the base. */ if (BINFO_VIRTUAL_P (subobject)) construct_virtual_base (subobject, arguments); @@ -1385,6 +1394,33 @@ expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags, return; } + /* If an explicit -- but empty -- initializer list was present, + 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_NEEDS_CONSTRUCTING (type)) + { + init = build_zero_init (type, NULL_TREE, /*static_storage_p=*/false); + 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)); + finish_expr_stmt (init); + return; + } + init = NULL_TREE; + } + /* We know that expand_default_init can handle everything we want at this point. */ expand_default_init (binfo, true_exp, exp, init, flags, complain); |