aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2008-12-03 18:57:19 -0500
committerJason Merrill <jason@gcc.gnu.org>2008-12-03 18:57:19 -0500
commit8f540f069535891aff80eab68f58ac1d4691c2c2 (patch)
tree38f8a82d1a414cec14d58ef9c8ed577e4200187b
parentc39d1b46ffb3e78962d56e6d42ed93c1fb53eca2 (diff)
downloadgcc-8f540f069535891aff80eab68f58ac1d4691c2c2.zip
gcc-8f540f069535891aff80eab68f58ac1d4691c2c2.tar.gz
gcc-8f540f069535891aff80eab68f58ac1d4691c2c2.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/init.c71
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/init/value5.C17
4 files changed, 56 insertions, 41 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f8bf162..0c6ecf8 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
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
* parser.c (cp_parser_conversion_type_id): Diagnose
'operator auto' here.
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 39d87e3..d71b68b 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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
- TYPE, as described in [dcl.init]. If HAVE_CTOR is true, the initializer
- for an enclosing object is already calling the constructor for this
- object. */
+ TYPE, as described in [dcl.init]. */
-static tree
-build_value_init_1 (tree type, bool have_ctor)
+tree
+build_value_init (tree type)
{
/* [dcl.init]
@@ -300,17 +298,38 @@ build_value_init_1 (tree type, bool have_ctor)
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
(type,
build_special_member_call (NULL_TREE, complete_ctor_identifier,
NULL_TREE, type, LOOKUP_NORMAL,
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)
{
- tree field, init;
+ tree field;
VEC(constructor_elt,gc) *v = NULL;
- bool call_ctor = !have_ctor && TYPE_NEEDS_CONSTRUCTING (type);
/* Iterate over the fields, building initializations. */
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
@@ -335,35 +354,14 @@ build_value_init_1 (tree type, bool have_ctor)
corresponding to base classes as well. Thus, iterating
over TYPE_FIELDs will result in correct initialization of
all of the subobjects. */
- value = build_value_init_1 (ftype, have_ctor || call_ctor);
+ value = build_value_init (ftype);
if (value)
CONSTRUCTOR_APPEND_ELT(v, field, value);
}
/* Build a constructor to contain the zero- initializations. */
- init = 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;
+ return build_constructor (type, v);
}
}
else if (TREE_CODE (type) == ARRAY_TYPE)
@@ -395,7 +393,7 @@ build_value_init_1 (tree type, bool have_ctor)
ce->index = build2 (RANGE_EXPR, sizetype, size_zero_node,
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. */
gcc_assert (TREE_CODE (ce->value) != TARGET_EXPR
@@ -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 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
arguments. If TREE_LIST is void_type_node, an empty initializer
list was given; if NULL_TREE no initializer was given. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index aa6c8e5..8156ee1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -8,6 +8,9 @@
2008-12-03 Jason Merrill <jason@redhat.com>
+ PR c++/38232
+ * g++.dg/init/value5.C: New test.
+
PR c++/38256
* g++.dg/cpp0x/auto11.C: New test.
diff --git a/gcc/testsuite/g++.dg/init/value5.C b/gcc/testsuite/g++.dg/init/value5.C
new file mode 100644
index 0000000..d705f87
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/value5.C
@@ -0,0 +1,17 @@
+// 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();
+}