]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/50930 ([C++0x] Valid brace-or-equal-initializer of non-static data member...
authorJason Merrill <jason@redhat.com>
Wed, 2 Nov 2011 21:24:56 +0000 (17:24 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 2 Nov 2011 21:24:56 +0000 (17:24 -0400)
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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/init.c
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/nsdmi-list2.C [new file with mode: 0644]

index 564203aae2155f01d461d772369edf2625804279..88f7d020b323f491e60d427ac5c8e18601271922 100644 (file)
@@ -1,5 +1,15 @@
 2011-11-02  Jason Merrill  <jason@redhat.com>
 
+       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.
+
        * parser.c (cp_parser_decl_specifier_seq): Change "C++0x" to
        "C++11" in warnings.
        (cp_lexer_get_preprocessor_token): Likewise.
index 439a1fe7c4f3001a41785003f833b8c4ff8fa648..ce8933afda9f764d690b33af050f31a8da503a65 100644 (file)
@@ -5655,10 +5655,14 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
            && CONSTRUCTOR_NELTS (expr) == 0
            && TYPE_HAS_DEFAULT_CONSTRUCTOR (totype))
          {
+           bool direct = CONSTRUCTOR_IS_DIRECT_INIT (expr);
            expr = build_value_init (totype, complain);
            expr = get_target_expr_sfinae (expr, complain);
            if (expr != error_mark_node)
-             TARGET_EXPR_LIST_INIT_P (expr) = true;
+             {
+               TARGET_EXPR_LIST_INIT_P (expr) = true;
+               TARGET_EXPR_DIRECT_INIT_P (expr) = direct;
+             }
            return expr;
          }
 
index 6b57eb60a6543eb852bebd97658ee707acbaa3a9..ec7ba0e802a428acdd565c55b6a76fcdd858acc5 100644 (file)
@@ -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);
index 707f2c8aeba9923658246c4013feb06ef02502b6..dc9fc954e41908b195760fa4dbae2117df9f2020 100644 (file)
@@ -1889,6 +1889,10 @@ bot_manip (tree* tp, int* walk_subtrees, void* data)
        u = build_target_expr_with_type (TREE_OPERAND (t, 1), TREE_TYPE (t),
                                         tf_warning_or_error);
 
+      TARGET_EXPR_IMPLICIT_P (u) = TARGET_EXPR_IMPLICIT_P (t);
+      TARGET_EXPR_LIST_INIT_P (u) = TARGET_EXPR_LIST_INIT_P (t);
+      TARGET_EXPR_DIRECT_INIT_P (u) = TARGET_EXPR_DIRECT_INIT_P (t);
+
       /* Map the old variable to the new one.  */
       splay_tree_insert (target_remap,
                         (splay_tree_key) TREE_OPERAND (t, 0),
index 2975ff2cec37da8ba7ded680dadf3d8b9b9620b5..52ca3c930167583f6eb73d067f6ec5dd16425dd3 100644 (file)
@@ -1,3 +1,8 @@
+2011-11-02  Jason Merrill  <jason@redhat.com>
+
+       PR c++/50930
+       * g++.dg/cpp0x/nsdmi-list2.C: New.
+
 2011-11-02  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/50810
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-list2.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-list2.C
new file mode 100644 (file)
index 0000000..a6321ff
--- /dev/null
@@ -0,0 +1,32 @@
+// PR c++/50930
+// { dg-options -std=c++0x }
+
+struct nmc {
+ nmc() = default;
+ nmc(nmc&&) = delete; // line 3
+};
+
+struct A { // line 6
+ nmc n{};
+ nmc n2 = {};
+} a; // line 8
+
+// ------
+
+struct lock_t {
+  int lock[4];
+};
+
+struct pthread_mutex_t {
+  volatile lock_t __spinlock;
+};
+
+struct mutex {
+  pthread_mutex_t m = { };
+  mutex() = default;
+};
+
+int main()
+{
+  mutex mx;
+}