From 8f540f069535891aff80eab68f58ac1d4691c2c2 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 3 Dec 2008 18:57:19 -0500 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 6 ++++ gcc/cp/init.c | 71 ++++++++++++++++---------------------- gcc/testsuite/ChangeLog | 3 ++ gcc/testsuite/g++.dg/init/value5.C | 17 +++++++++ 4 files changed, 56 insertions(+), 41 deletions(-) create mode 100644 gcc/testsuite/g++.dg/init/value5.C 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 + 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 + 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(); +} -- 2.7.4