diff options
author | Jason Merrill <jason@redhat.com> | 2011-11-02 17:24:56 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2011-11-02 17:24:56 -0400 |
commit | e08cc018ac1ed9e201d064c52d0a378b7014e636 (patch) | |
tree | 5cbcad8071adf2d4745f46369c097544401fe5d8 /gcc/cp/init.c | |
parent | 537e309ce321c058535a935e37b005069ef388d5 (diff) | |
download | gcc-e08cc018ac1ed9e201d064c52d0a378b7014e636.zip gcc-e08cc018ac1ed9e201d064c52d0a378b7014e636.tar.gz gcc-e08cc018ac1ed9e201d064c52d0a378b7014e636.tar.bz2 |
re PR c++/50930 ([C++0x] Valid brace-or-equal-initializer of non-static data member rejected)
PR c++/50930
* init.c (build_aggr_init): Don't set LOOKUP_ONLYCONVERTING
if the initializer has TARGET_EXPR_DIRECT_INIT_P.
(expand_default_init): An initializer with TARGET_EXPR_DIRECT_INIT_P
or TARGET_EXPR_LIST_INIT_P doesn't need more processing.
* tree.c (bot_manip): Propagate TARGET_EXPR_IMPLICIT_P,
TARGET_EXPR_LIST_INIT_P, TARGET_EXPR_DIRECT_INIT_P.
* call.c (convert_like_real): Set TARGET_EXPR_DIRECT_INIT_P
as appropriate on list-value-initialization.
From-SVN: r180802
Diffstat (limited to 'gcc/cp/init.c')
-rw-r--r-- | gcc/cp/init.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 6b57eb6..ec7ba0e 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1377,6 +1377,8 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain) TREE_THIS_VOLATILE (exp) = 0; if (init && TREE_CODE (init) != TREE_LIST + && !(TREE_CODE (init) == TARGET_EXPR + && TARGET_EXPR_DIRECT_INIT_P (init)) && !(BRACE_ENCLOSED_INITIALIZER_P (init) && CONSTRUCTOR_IS_DIRECT_INIT (init))) flags |= LOOKUP_ONLYCONVERTING; @@ -1459,10 +1461,28 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags, if (init && BRACE_ENCLOSED_INITIALIZER_P (init) && CP_AGGREGATE_TYPE_P (type)) + /* A brace-enclosed initializer for an aggregate. In C++0x this can + happen for direct-initialization, too. */ + init = digest_init (type, init, complain); + + /* A CONSTRUCTOR of the target's type is a previously digested + initializer, whether that happened just above or in + cp_parser_late_parsing_nsdmi. + + A TARGET_EXPR with TARGET_EXPR_DIRECT_INIT_P or TARGET_EXPR_LIST_INIT_P + set represents the whole initialization, so we shouldn't build up + another ctor call. */ + if (init + && (TREE_CODE (init) == CONSTRUCTOR + || (TREE_CODE (init) == TARGET_EXPR + && (TARGET_EXPR_DIRECT_INIT_P (init) + || TARGET_EXPR_LIST_INIT_P (init)))) + && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (init), type)) { - /* A brace-enclosed initializer for an aggregate. In C++0x this can - happen for direct-initialization, too. */ - init = digest_init (type, init, complain); + /* Early initialization via a TARGET_EXPR only works for + complete objects. */ + gcc_assert (TREE_CODE (init) == CONSTRUCTOR || true_exp == exp); + init = build2 (INIT_EXPR, TREE_TYPE (exp), exp, init); TREE_SIDE_EFFECTS (init) = 1; finish_expr_stmt (init); |