aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-02-09 16:46:18 -0500
committerJason Merrill <jason@gcc.gnu.org>2009-02-09 16:46:18 -0500
commit450a927a7a65632a4aca39258ff2dd943802196e (patch)
tree82fa13f1148b5e6f8aca8bed6ab67a8e148af277
parent9a3b094ff2c230c3b8294ace002c77f28cfc1994 (diff)
downloadgcc-450a927a7a65632a4aca39258ff2dd943802196e.zip
gcc-450a927a7a65632a4aca39258ff2dd943802196e.tar.gz
gcc-450a927a7a65632a4aca39258ff2dd943802196e.tar.bz2
re PR c++/39109 (Accessible constructor required for new)
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
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/cp-gimplify.c8
-rw-r--r--gcc/cp/cp-tree.h5
-rw-r--r--gcc/cp/init.c14
-rw-r--r--gcc/cp/semantics.c9
-rw-r--r--gcc/cp/tree.c5
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/init/value6.C13
8 files changed, 49 insertions, 20 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 690334d..2db00fd 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 99738ea..838a9d6 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -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;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f37c888..87eefa3 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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). */
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index f2b79f1..d4dafed 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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)
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index c9f0641..55b0bae 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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;
}
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 04fc7e9..606a946 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4bf47cc..ebd148d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..d7d29bf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/value6.C
@@ -0,0 +1,13 @@
+// PR c++/39109
+
+struct N
+{
+ private:
+ virtual ~N ();
+};
+
+N *
+foo ()
+{
+ return new N ();
+}