From 3922bea3f5457e181df1eccf75fa82785ca3ff2c Mon Sep 17 00:00:00 2001 From: jason Date: Wed, 17 Feb 2010 22:51:51 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/call.c | 24 ++++++++++++++++++++++-- gcc/cp/cp-gimplify.c | 9 --------- gcc/cp/cp-objcp-common.c | 43 ------------------------------------------- gcc/cp/cp-tree.h | 1 - 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 + 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 *); -- 2.11.4.GIT