summaryrefslogtreecommitdiff
path: root/gcc/cp/call.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/call.c')
-rw-r--r--gcc/cp/call.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 54254c37f1d..5e66c625295 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -5782,8 +5782,20 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
{
tree to = stabilize_reference (cp_build_indirect_ref (fa, RO_NULL,
complain));
+ tree type = TREE_TYPE (to);
- val = build2 (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
+ if (TREE_CODE (arg) != TARGET_EXPR
+ && TREE_CODE (arg) != AGGR_INIT_EXPR
+ && is_really_empty_class (type))
+ {
+ /* Avoid copying empty classes. */
+ val = build2 (COMPOUND_EXPR, void_type_node, to, arg);
+ TREE_NO_WARNING (val) = 1;
+ val = build2 (COMPOUND_EXPR, type, val, to);
+ TREE_NO_WARNING (val) = 1;
+ }
+ else
+ val = build2 (INIT_EXPR, DECL_CONTEXT (fn), to, arg);
return val;
}
}
@@ -5797,7 +5809,15 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
tree as_base = CLASSTYPE_AS_BASE (type);
tree arg = argarray[1];
- if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
+ if (is_really_empty_class (type))
+ {
+ /* Avoid copying empty classes. */
+ val = build2 (COMPOUND_EXPR, void_type_node, to, arg);
+ TREE_NO_WARNING (val) = 1;
+ val = build2 (COMPOUND_EXPR, type, val, to);
+ TREE_NO_WARNING (val) = 1;
+ }
+ else if (tree_int_cst_equal (TYPE_SIZE (type), TYPE_SIZE (as_base)))
{
arg = cp_build_indirect_ref (arg, RO_NULL, complain);
val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg);