So, the problem in 48834 was that we had specified a particular target for the vec initialization, but it was getting clobbered by ending up on the rhs of an INIT_EXPR. So 48834.patch avoids that.

But Diego doesn't think there was any real reason to abort on trying to copy a STATEMENT_LIST, so it seems to me that we could revert my earlier patch for 40975 and just add support for copying STATEMENT_LIST. So 40975-2.patch adds that support. I haven't attached a patch to revert my earlier 40975 patch.

Some of the incidental changes from my earlier patch seem independently useful, so I'm reapplying those in vec-sfinae.patch.

Tested x86_64-pc-linux-gnu, applying to trunk. Also applying 40975-2.patch to 4.4, 4.5 and 4.6; it doesn't fix the bug in 4.3 so I'm not applying it there.
commit 41d391e1683e6ed7e28ad31f41732b3f4b691baa
Author: Jason Merrill <ja...@redhat.com>
Date:   Mon May 2 01:36:01 2011 -0400

        PR c++/48834
        * tree.c (build_vec_init_expr): Set TREE_SIDE_EFFECTS.
        Protect an explicit target.

diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 2eaa1db..fff3fbf 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -564,6 +564,7 @@ build_vec_init_expr (tree target, tree init, tree nelts,
     elt_init = build_vec_init_elt (type, init, complain);
 
   init = build3 (VEC_INIT_EXPR, type, slot, init, nelts);
+  TREE_SIDE_EFFECTS (init) = true;
   SET_EXPR_LOCATION (init, input_location);
 
   if (cxx_dialect >= cxx0x
@@ -571,7 +572,11 @@ build_vec_init_expr (tree target, tree init, tree nelts,
     VEC_INIT_EXPR_IS_CONSTEXPR (init) = true;
   VEC_INIT_EXPR_VALUE_INIT (init) = value_init;
 
-  if (slot != target)
+  if (slot == target)
+    /* If we specified what array we're initializing, make sure
+       we don't override that in cp_gimplify_init_expr.  */
+    init = cp_build_compound_expr (init, slot, complain);
+  else
     {
       init = build_target_expr (slot, init, complain);
       TARGET_EXPR_IMPLICIT_P (init) = 1;
diff --git a/gcc/testsuite/g++.dg/init/new31.C 
b/gcc/testsuite/g++.dg/init/new31.C
new file mode 100644
index 0000000..33c94aa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/new31.C
@@ -0,0 +1,18 @@
+// PR c++/48834
+// { dg-options -Wuninitialized }
+// { dg-do run }
+
+struct S
+{
+  S ():i (0)
+  {
+  }
+  int i;
+};
+
+int
+main ()
+{
+  S *s = new S[2];
+  return 0;
+}
commit 98011319607130da27331a5f1b763ba8ce741734
Author: Jason Merrill <ja...@redhat.com>
Date:   Mon May 2 16:02:29 2011 -0400

        PR c++/40975
        * tree-inline.c (copy_tree_r): Handle STATEMENT_LIST.

diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 5da4a12..3777675 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -4271,14 +4271,26 @@ copy_tree_r (tree *tp, int *walk_subtrees, void *data 
ATTRIBUTE_UNUSED)
                                         CONSTRUCTOR_ELTS (*tp));
       *tp = new_tree;
     }
+  else if (code == STATEMENT_LIST)
+    {
+      /* We used to just abort on STATEMENT_LIST, but we can run into them
+         with statement-expressions (c++/40975).  */
+      tree new_list = alloc_stmt_list ();
+      tree_stmt_iterator i = tsi_start (*tp);
+      tree_stmt_iterator j = tsi_last (new_list);
+      for (; !tsi_end_p (i); tsi_next (&i))
+       {
+         tree stmt = tsi_stmt (i);
+         tsi_link_after (&j, stmt, TSI_CONTINUE_LINKING);
+       }
+      *tp = new_list;
+    }
   else if (TREE_CODE_CLASS (code) == tcc_type)
     *walk_subtrees = 0;
   else if (TREE_CODE_CLASS (code) == tcc_declaration)
     *walk_subtrees = 0;
   else if (TREE_CODE_CLASS (code) == tcc_constant)
     *walk_subtrees = 0;
-  else
-    gcc_assert (code != STATEMENT_LIST);
   return NULL_TREE;
 }
 
commit 6f60af2d7324b81f4b524c34c321280e4874c2ee
Author: Jason Merrill <ja...@redhat.com>
Date:   Mon May 2 17:02:10 2011 -0400

        * tree.c (build_vec_init_expr): Take complain parm.
        (build_vec_init_elt): Likewise.  Free arg vector.
        (diagnose_non_constexpr_vec_init, build_array_copy): Adjust.
        * cp-tree.h (VEC_INIT_EXPR_SLOT): Use VEC_INIT_EXPR_CHECK.
        (VEC_INIT_EXPR_INIT): Likewise.
        Adjust build_vec_init_expr declaration.
        * init.c (perform_member_init): Adjust.

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 9bad404..961581e 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -2896,8 +2896,8 @@ more_aggr_init_expr_args_p (const 
aggr_init_expr_arg_iterator *iter)
        (arg) = next_aggr_init_expr_arg (&(iter)))
 
 /* VEC_INIT_EXPR accessors.  */
-#define VEC_INIT_EXPR_SLOT(NODE) TREE_OPERAND (NODE, 0)
-#define VEC_INIT_EXPR_INIT(NODE) TREE_OPERAND (NODE, 1)
+#define VEC_INIT_EXPR_SLOT(NODE) TREE_OPERAND (VEC_INIT_EXPR_CHECK (NODE), 0)
+#define VEC_INIT_EXPR_INIT(NODE) TREE_OPERAND (VEC_INIT_EXPR_CHECK (NODE), 1)
 
 /* Indicates that a VEC_INIT_EXPR is a potential constant expression.
    Only set when the current function is constexpr.  */
@@ -5420,7 +5420,7 @@ extern tree get_target_expr_sfinae                (tree, 
tsubst_flags_t);
 extern tree build_cplus_array_type             (tree, tree);
 extern tree build_array_of_n_type              (tree, int);
 extern tree build_array_copy                   (tree);
-extern tree build_vec_init_expr                        (tree, tree);
+extern tree build_vec_init_expr                        (tree, tree, 
tsubst_flags_t);
 extern void diagnose_non_constexpr_vec_init    (tree);
 extern tree hash_tree_cons                     (tree, tree, tree);
 extern tree hash_tree_chain                    (tree, tree);
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 50dbcc9..7a7379e 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -506,7 +506,7 @@ perform_member_init (tree member, tree init)
       /* mem() means value-initialization.  */
       if (TREE_CODE (type) == ARRAY_TYPE)
        {
-         init = build_vec_init_expr (type, init);
+         init = build_vec_init_expr (type, init, tf_warning_or_error);
          init = build2 (INIT_EXPR, type, decl, init);
          finish_expr_stmt (init);
        }
@@ -543,7 +543,7 @@ perform_member_init (tree member, tree init)
              || same_type_ignoring_top_level_qualifiers_p (type,
                                                            TREE_TYPE (init)))
            {
-             init = build_vec_init_expr (type, init);
+             init = build_vec_init_expr (type, init, tf_warning_or_error);
              init = build2 (INIT_EXPR, type, decl, init);
              finish_expr_stmt (init);
            }
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index dfd11ad..0f2f86c 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -475,7 +475,7 @@ build_cplus_new (tree type, tree init, tsubst_flags_t 
complain)
    another array to copy.  */
 
 static tree
-build_vec_init_elt (tree type, tree init)
+build_vec_init_elt (tree type, tree init, tsubst_flags_t complain)
 {
   tree inner_type = strip_array_types (type);
   VEC(tree,gc) *argvec;
@@ -485,7 +485,7 @@ build_vec_init_elt (tree type, tree init)
     /* No interesting initialization to do.  */
     return integer_zero_node;
   else if (init == void_type_node)
-    return build_value_init (inner_type, tf_warning_or_error);
+    return build_value_init (inner_type, complain);
 
   gcc_assert (init == NULL_TREE
              || (same_type_ignoring_top_level_qualifiers_p
@@ -499,9 +499,12 @@ build_vec_init_elt (tree type, tree init)
        dummy = move (dummy);
       VEC_quick_push (tree, argvec, dummy);
     }
-  return build_special_member_call (NULL_TREE, complete_ctor_identifier,
+  init = build_special_member_call (NULL_TREE, complete_ctor_identifier,
                                    &argvec, inner_type, LOOKUP_NORMAL,
-                                   tf_warning_or_error);
+                                   complain);
+  release_tree_vector (argvec);
+
+  return init;
 }
 
 /* Return a TARGET_EXPR which expresses the initialization of an array to
@@ -509,11 +512,11 @@ build_vec_init_elt (tree type, tree init)
    from another array of the same type.  */
 
 tree
-build_vec_init_expr (tree type, tree init)
+build_vec_init_expr (tree type, tree init, tsubst_flags_t complain)
 {
   tree slot;
   bool value_init = false;
-  tree elt_init = build_vec_init_elt (type, init);
+  tree elt_init = build_vec_init_elt (type, init, complain);
 
   if (init == void_type_node)
     {
@@ -550,14 +553,14 @@ diagnose_non_constexpr_vec_init (tree expr)
   else
     init = VEC_INIT_EXPR_INIT (expr);
 
-  elt_init = build_vec_init_elt (type, init);
+  elt_init = build_vec_init_elt (type, init, tf_warning_or_error);
   require_potential_constant_expression (elt_init);
 }
 
 tree
 build_array_copy (tree init)
 {
-  return build_vec_init_expr (TREE_TYPE (init), init);
+  return build_vec_init_expr (TREE_TYPE (init), init, tf_warning_or_error);
 }
 
 /* Build a TARGET_EXPR using INIT to initialize a new temporary of the

Reply via email to