re PR c++/39109 (Accessible constructor required for new)
authorJason Merrill <jason@redhat.com>
Mon, 9 Feb 2009 21:46:18 +0000 (16:46 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 9 Feb 2009 21:46:18 +0000 (16:46 -0500)
        PR c++/39109
        * semantics.c (simplify_aggr_init_expr): Do zero-initialization here.
        * init.c (build_value_init): Not here. Don't build a TARGET_EXPR.
        * tree.c (get_target_expr): Handle AGGR_INIT_EXPR.
        * cp-gimplify.c (cp_gimplify_init_expr): Remove special handling
        for build_value_init TARGET_EXPR.
        * cp-tree.h (AGGR_INIT_ZERO_FIRST): New macro.

From-SVN: r144044

gcc/cp/ChangeLog
gcc/cp/cp-gimplify.c
gcc/cp/cp-tree.h
gcc/cp/init.c
gcc/cp/semantics.c
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/init/value6.C [new file with mode: 0644]

index 690334d6e453f8e0a323a51fe4c9a87f38580b4c..2db00fd979b12fc2b40317200322a0fbc2e587ee 100644 (file)
@@ -1,3 +1,13 @@
+2009-02-09  Jason Merrill  <jason@redhat.com>
+
+       PR c++/39109
+       * semantics.c (simplify_aggr_init_expr): Do zero-initialization here.
+       * init.c (build_value_init): Not here. Don't build a TARGET_EXPR.
+       * tree.c (get_target_expr): Handle AGGR_INIT_EXPR.
+       * cp-gimplify.c (cp_gimplify_init_expr): Remove special handling
+       for build_value_init TARGET_EXPR.
+       * cp-tree.h (AGGR_INIT_ZERO_FIRST): New macro.
+
 2009-02-06  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/35147
index 99738eac72e542054cfe837779568cdaacd0236b..838a9d6fa423f0efe29649d3f03bbd93ff7200f9 100644 (file)
@@ -460,14 +460,6 @@ cp_gimplify_init_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
          if (from != sub)
            TREE_TYPE (from) = void_type_node;
        }
-      else if (TREE_CODE (sub) == INIT_EXPR
-              && TREE_OPERAND (sub, 0) == slot)
-       {
-         /* An INIT_EXPR under TARGET_EXPR created by build_value_init,
-            will be followed by an AGGR_INIT_EXPR.  */
-         gimplify_expr (&to, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
-         TREE_OPERAND (sub, 0) = to;
-       }
 
       if (t == sub)
        break;
index f37c88836887c2db6b0fa31ef1f152ce981e67e1..87eefa33437ef1b62753b7d6ce7a13ef0219facd 100644 (file)
@@ -2492,6 +2492,11 @@ extern void decl_shadowed_for_var_insert (tree, tree);
 #define AGGR_INIT_VIA_CTOR_P(NODE) \
   TREE_LANG_FLAG_0 (AGGR_INIT_EXPR_CHECK (NODE))
 
+/* Nonzero if expanding this AGGR_INIT_EXPR should first zero-initialize
+   the object.  */
+#define AGGR_INIT_ZERO_FIRST(NODE) \
+  TREE_LANG_FLAG_2 (AGGR_INIT_EXPR_CHECK (NODE))
+
 /* AGGR_INIT_EXPR accessors.  These are equivalent to the CALL_EXPR
    accessors, except for AGGR_INIT_EXPR_SLOT (which takes the place of
    CALL_EXPR_STATIC_CHAIN).  */
index f2b79f18899aa3978adff3f174303046b9e39457..d4dafedd54fdd5f8e2ca4ea363f9f838e71daa77 100644 (file)
@@ -309,21 +309,13 @@ build_value_init (tree 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);
+            This will be handled in simplify_aggr_init_expr.  */
          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;
+         ctor = build_aggr_init_expr (type, ctor);
+         AGGR_INIT_ZERO_FIRST (ctor) = 1;
          return ctor;
        }
       else if (TREE_CODE (type) != UNION_TYPE)
index c9f0641f5f8452ace0325ee8ca6613f3cfbb2009..55b0bae6cbb32643a3e804ad0073edeed7fcfb60 100644 (file)
@@ -3125,6 +3125,15 @@ simplify_aggr_init_expr (tree *tp)
       call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (slot), call_expr, slot);
     }
 
+  if (AGGR_INIT_ZERO_FIRST (aggr_init_expr))
+    {
+      tree init = build_zero_init (type, NULL_TREE,
+                                  /*static_storage_p=*/false);
+      init = build2 (INIT_EXPR, void_type_node, slot, init);
+      call_expr = build2 (COMPOUND_EXPR, TREE_TYPE (call_expr),
+                         init, call_expr);
+    }
+
   *tp = call_expr;
 }
 
index 04fc7e930aa9b7a3f1dd4bd2dcc58d07eca361cf..606a94649745d03c0e3efc59176064dd200327d6 100644 (file)
@@ -487,7 +487,10 @@ force_target_expr (tree type, tree init)
 tree
 get_target_expr (tree init)
 {
-  return build_target_expr_with_type (init, TREE_TYPE (init));
+  if (TREE_CODE (init) == AGGR_INIT_EXPR)
+    return build_target_expr (AGGR_INIT_EXPR_SLOT (init), init);
+  else
+    return build_target_expr_with_type (init, TREE_TYPE (init));
 }
 
 /* If EXPR is a bitfield reference, convert it to the declared type of
index 4bf47cc75050d181205719f47232104c5088313a..ebd148d9cdfa2755f35cec9004dcc0c9bfe10688 100644 (file)
@@ -1,3 +1,8 @@
+2009-02-09  Jason Merrill  <jason@redhat.com>
+
+       PR c++/39109
+       * g++.dg/init/value6.C: New test.
+
 2009-02-09  H.J. Lu  <hongjiu.lu@intel.com>
 
        * gcc.target/x86_64/abi/abi-x86_64.exp: Use glob instead of
diff --git a/gcc/testsuite/g++.dg/init/value6.C b/gcc/testsuite/g++.dg/init/value6.C
new file mode 100644 (file)
index 0000000..d7d29bf
--- /dev/null
@@ -0,0 +1,13 @@
+// PR c++/39109
+
+struct N
+{
+  private:
+    virtual ~N ();
+};
+
+N *
+foo ()
+{
+  return new N ();
+}