Commit 8f540f06 by Jason Merrill Committed by Jason Merrill

re PR c++/38232 ("value-initialization of reference" warning too strict)

        PR c++/38232
        * init.c (build_value_init): Do initial zero-initialization
        of a class with an implicitly-defined constructor using
        build_zero_init rather than in build_value_init.
        (build_value_init_1): Fold into build_value_init.

From-SVN: r142418
parent c39d1b46
2008-12-03 Jason Merrill <jason@redhat.com> 2008-12-03 Jason Merrill <jason@redhat.com>
PR c++/38232
* init.c (build_value_init): Do initial zero-initialization
of a class with an implicitly-defined constructor using
build_zero_init rather than in build_value_init.
(build_value_init_1): Fold into build_value_init.
PR c++/38256 PR c++/38256
* parser.c (cp_parser_conversion_type_id): Diagnose * parser.c (cp_parser_conversion_type_id): Diagnose
'operator auto' here. 'operator auto' here.
......
...@@ -267,12 +267,10 @@ build_zero_init (tree type, tree nelts, bool static_storage_p) ...@@ -267,12 +267,10 @@ build_zero_init (tree type, tree nelts, bool static_storage_p)
} }
/* Return a suitable initializer for value-initializing an object of type /* Return a suitable initializer for value-initializing an object of type
TYPE, as described in [dcl.init]. If HAVE_CTOR is true, the initializer TYPE, as described in [dcl.init]. */
for an enclosing object is already calling the constructor for this
object. */
static tree tree
build_value_init_1 (tree type, bool have_ctor) build_value_init (tree type)
{ {
/* [dcl.init] /* [dcl.init]
...@@ -300,17 +298,38 @@ build_value_init_1 (tree type, bool have_ctor) ...@@ -300,17 +298,38 @@ build_value_init_1 (tree type, bool have_ctor)
if (CLASS_TYPE_P (type)) if (CLASS_TYPE_P (type))
{ {
if (type_has_user_provided_constructor (type) && !have_ctor) if (type_has_user_provided_constructor (type))
return build_aggr_init_expr return build_aggr_init_expr
(type, (type,
build_special_member_call (NULL_TREE, complete_ctor_identifier, build_special_member_call (NULL_TREE, complete_ctor_identifier,
NULL_TREE, type, LOOKUP_NORMAL, NULL_TREE, type, LOOKUP_NORMAL,
tf_warning_or_error)); tf_warning_or_error));
else if (TREE_CODE (type) != UNION_TYPE && TYPE_NEEDS_CONSTRUCTING (type))
{
/* This is a class that needs constructing, but doesn't have
a user-provided constructor. So we need to zero-initialize
the object and then call the implicitly defined ctor.
Implement this by sticking the zero-initialization inside
the TARGET_EXPR for the constructor call;
cp_gimplify_init_expr will know how to handle it. */
tree init = build_zero_init (type, NULL_TREE,
/*static_storage_p=*/false);
tree ctor = build_special_member_call
(NULL_TREE, complete_ctor_identifier,
NULL_TREE, type, LOOKUP_NORMAL, tf_warning_or_error);
ctor = build_cplus_new (type, ctor);
init = build2 (INIT_EXPR, void_type_node,
TARGET_EXPR_SLOT (ctor), init);
init = build2 (COMPOUND_EXPR, void_type_node, init,
TARGET_EXPR_INITIAL (ctor));
TARGET_EXPR_INITIAL (ctor) = init;
return ctor;
}
else if (TREE_CODE (type) != UNION_TYPE) else if (TREE_CODE (type) != UNION_TYPE)
{ {
tree field, init; tree field;
VEC(constructor_elt,gc) *v = NULL; VEC(constructor_elt,gc) *v = NULL;
bool call_ctor = !have_ctor && TYPE_NEEDS_CONSTRUCTING (type);
/* Iterate over the fields, building initializations. */ /* Iterate over the fields, building initializations. */
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
...@@ -335,35 +354,14 @@ build_value_init_1 (tree type, bool have_ctor) ...@@ -335,35 +354,14 @@ build_value_init_1 (tree type, bool have_ctor)
corresponding to base classes as well. Thus, iterating corresponding to base classes as well. Thus, iterating
over TYPE_FIELDs will result in correct initialization of over TYPE_FIELDs will result in correct initialization of
all of the subobjects. */ all of the subobjects. */
value = build_value_init_1 (ftype, have_ctor || call_ctor); value = build_value_init (ftype);
if (value) if (value)
CONSTRUCTOR_APPEND_ELT(v, field, value); CONSTRUCTOR_APPEND_ELT(v, field, value);
} }
/* Build a constructor to contain the zero- initializations. */ /* Build a constructor to contain the zero- initializations. */
init = build_constructor (type, v); return build_constructor (type, v);
if (call_ctor)
{
/* This is a class that needs constructing, but doesn't have
a user-defined constructor. So we need to zero-initialize
the object and then call the implicitly defined ctor.
Implement this by sticking the zero-initialization inside
the TARGET_EXPR for the constructor call;
cp_gimplify_init_expr will know how to handle it. */
tree ctor = build_special_member_call
(NULL_TREE, complete_ctor_identifier,
NULL_TREE, type, LOOKUP_NORMAL, tf_warning_or_error);
ctor = build_cplus_new (type, ctor);
init = build2 (INIT_EXPR, void_type_node,
TARGET_EXPR_SLOT (ctor), init);
init = build2 (COMPOUND_EXPR, void_type_node, init,
TARGET_EXPR_INITIAL (ctor));
TARGET_EXPR_INITIAL (ctor) = init;
return ctor;
}
return init;
} }
} }
else if (TREE_CODE (type) == ARRAY_TYPE) else if (TREE_CODE (type) == ARRAY_TYPE)
...@@ -395,7 +393,7 @@ build_value_init_1 (tree type, bool have_ctor) ...@@ -395,7 +393,7 @@ build_value_init_1 (tree type, bool have_ctor)
ce->index = build2 (RANGE_EXPR, sizetype, size_zero_node, ce->index = build2 (RANGE_EXPR, sizetype, size_zero_node,
max_index); max_index);
ce->value = build_value_init_1 (TREE_TYPE (type), have_ctor); ce->value = build_value_init (TREE_TYPE (type));
/* The gimplifier can't deal with a RANGE_EXPR of TARGET_EXPRs. */ /* The gimplifier can't deal with a RANGE_EXPR of TARGET_EXPRs. */
gcc_assert (TREE_CODE (ce->value) != TARGET_EXPR gcc_assert (TREE_CODE (ce->value) != TARGET_EXPR
...@@ -409,15 +407,6 @@ build_value_init_1 (tree type, bool have_ctor) ...@@ -409,15 +407,6 @@ build_value_init_1 (tree type, bool have_ctor)
return build_zero_init (type, NULL_TREE, /*static_storage_p=*/false); return build_zero_init (type, NULL_TREE, /*static_storage_p=*/false);
} }
/* Return a suitable initializer for value-initializing an object of type
TYPE, as described in [dcl.init]. */
tree
build_value_init (tree type)
{
return build_value_init_1 (type, false);
}
/* Initialize MEMBER, a FIELD_DECL, with INIT, a TREE_LIST of /* Initialize MEMBER, a FIELD_DECL, with INIT, a TREE_LIST of
arguments. If TREE_LIST is void_type_node, an empty initializer arguments. If TREE_LIST is void_type_node, an empty initializer
list was given; if NULL_TREE no initializer was given. */ list was given; if NULL_TREE no initializer was given. */
......
...@@ -8,6 +8,9 @@ ...@@ -8,6 +8,9 @@
2008-12-03 Jason Merrill <jason@redhat.com> 2008-12-03 Jason Merrill <jason@redhat.com>
PR c++/38232
* g++.dg/init/value5.C: New test.
PR c++/38256 PR c++/38256
* g++.dg/cpp0x/auto11.C: New test. * g++.dg/cpp0x/auto11.C: New test.
......
// PR c++/38232
class base {
public:
base();
virtual ~base();
private:
int& int_ref; // initialized by base ctor, not visible here
};
class derived : public base {
};
base *make_derived() {
return new derived();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment