From: Jason Merrill Date: Mon, 9 Feb 2009 21:46:18 +0000 (-0500) Subject: re PR c++/39109 (Accessible constructor required for new) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=450a927a7a65632a4aca39258ff2dd943802196e;p=gcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 690334d6e45..2db00fd979b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2009-02-09 Jason Merrill + + 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 PR c++/35147 diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 99738eac72e..838a9d6fa42 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 f37c8883688..87eefa33437 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 f2b79f18899..d4dafedd54f 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 c9f0641f5f8..55b0bae6cbb 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 04fc7e930aa..606a9464974 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 4bf47cc7505..ebd148d9cdf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2009-02-09 Jason Merrill + + PR c++/39109 + * g++.dg/init/value6.C: New test. + 2009-02-09 H.J. Lu * 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 00000000000..d7d29bf0a3e --- /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 (); +}