aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-02-11 17:38:37 -0500
committerJason Merrill <jason@gcc.gnu.org>2009-02-11 17:38:37 -0500
commitfd97a96a1049407b248f9e6927f6021ba0e02115 (patch)
treedc134d4d594d3c5e37ab4a52debdc05c7516eaf9 /gcc/cp
parent3ad6b2669b7a6d9cd1b12330fd7accd44fdd2154 (diff)
downloadgcc-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/ChangeLog10
-rw-r--r--gcc/cp/class.c3
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/init.c48
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);