summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2010-02-17 22:51:51 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2010-02-17 22:51:51 +0000
commit3922bea3f5457e181df1eccf75fa82785ca3ff2c (patch)
tree2e7d21f1a571171af5e129b32829cd1f539a3818 /gcc/cp
parent253cc498054d02f859162e04e753e185713a1c5d (diff)
downloadgcc-3922bea3f5457e181df1eccf75fa82785ca3ff2c.tar.gz
PR c++/43075
* call.c (build_over_call): Don't create zero-sized assignments. * cp-gimplify.c (cp_genericize_r): Don't remove them here. * cp-objcp-common.c (cp_expr_size): Remove. * cp-tree.h: Remove prototype. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@156842 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/call.c24
-rw-r--r--gcc/cp/cp-gimplify.c9
-rw-r--r--gcc/cp/cp-objcp-common.c43
-rw-r--r--gcc/cp/cp-tree.h1
5 files changed, 28 insertions, 55 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ef12985789a..9ebc6095b1d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,11 @@
2010-02-17 Jason Merrill <jason@redhat.com>
+ PR c++/43075
+ * call.c (build_over_call): Don't create zero-sized assignments.
+ * cp-gimplify.c (cp_genericize_r): Don't remove them here.
+ * cp-objcp-common.c (cp_expr_size): Remove.
+ * cp-tree.h: Remove prototype.
+
PR c++/43069
* name-lookup.c (set_decl_namespace): Don't copy DECL_CONTEXT if the
decl we looked up doesn't match.
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);
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index df09b60c6dd..533d2d18384 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -884,15 +884,6 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
*walk_subtrees = 0;
}
- else if (TREE_CODE (stmt) == MODIFY_EXPR
- && (integer_zerop (cp_expr_size (TREE_OPERAND (stmt, 0)))
- || integer_zerop (cp_expr_size (TREE_OPERAND (stmt, 1)))))
- {
- *stmt_p = build2 (COMPOUND_EXPR, TREE_TYPE (stmt),
- TREE_OPERAND (stmt, 0),
- TREE_OPERAND (stmt, 1));
- }
-
pointer_set_insert (p_set, *stmt_p);
return NULL;
diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
index f06ad5b86c8..460f32fe13d 100644
--- a/gcc/cp/cp-objcp-common.c
+++ b/gcc/cp/cp-objcp-common.c
@@ -69,49 +69,6 @@ cxx_warn_unused_global_decl (const_tree decl)
return true;
}
-/* Langhook for expr_size: Tell the back end that the value of an expression
- of non-POD class type does not include any tail padding; a derived class
- might have allocated something there. */
-
-tree
-cp_expr_size (const_tree exp)
-{
- tree type = TREE_TYPE (exp);
-
- if (CLASS_TYPE_P (type))
- {
- /* The back end should not be interested in the size of an expression
- of a type with both of these set; all copies of such types must go
- through a constructor or assignment op. */
- if (!TYPE_HAS_COMPLEX_INIT_REF (type)
- || !TYPE_HAS_COMPLEX_ASSIGN_REF (type)
- /* But storing a CONSTRUCTOR isn't a copy. */
- || TREE_CODE (exp) == CONSTRUCTOR
- /* And, the gimplifier will sometimes make a copy of
- an aggregate. In particular, for a case like:
-
- struct S { S(); };
- struct X { int a; S s; };
- X x = { 0 };
-
- the gimplifier will create a temporary with
- static storage duration, perform static
- initialization of the temporary, and then copy
- the result. Since the "s" subobject is never
- constructed, this is a valid transformation. */
- || CP_AGGREGATE_TYPE_P (type))
- /* This would be wrong for a type with virtual bases. */
- return (is_really_empty_class (type)
- ? size_zero_node
- : CLASSTYPE_SIZE_UNIT (type));
- else
- return NULL_TREE;
- }
- else
- /* Use the default code. */
- return tree_expr_size (exp);
-}
-
/* Langhook for tree_size: determine size of our 'x' and 'c' nodes. */
size_t
cp_tree_size (enum tree_code code)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f32c6e86e5c..b5330a3ab8b 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5445,7 +5445,6 @@ extern bool cp_dump_tree (void *, tree);
extern alias_set_type cxx_get_alias_set (tree);
extern bool cxx_warn_unused_global_decl (const_tree);
-extern tree cp_expr_size (const_tree);
extern size_t cp_tree_size (enum tree_code);
extern bool cp_var_mod_type_p (tree, tree);
extern void cxx_initialize_diagnostics (struct diagnostic_context *);