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
This commit is contained in:
Jason Merrill 2009-02-11 17:38:37 -05:00 committed by Jason Merrill
parent 3ad6b2669b
commit fd97a96a10
6 changed files with 78 additions and 6 deletions

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -1,3 +1,8 @@
2009-02-11 Jason Merrill <jason@redhat.com>
PR c++/30111
* g++.dg/init/value7.C: New test.
2009-02-11 Paolo Bonzini <bonzini@gnu.org>
* gcc.target/i386/pr38824.c: New testcase.

View File

@ -0,0 +1,17 @@
// PR c++/30111
// { dg-do run }
struct pod {
int i;
};
struct inherit : pod {
inherit() : pod() {}
};
int main()
{
inherit i;
return i.i != 0;
}