+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
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;
#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). */
/* 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)
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;
}
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
+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
--- /dev/null
+// PR c++/39109
+
+struct N
+{
+ private:
+ virtual ~N ();
+};
+
+N *
+foo ()
+{
+ return new N ();
+}