Commit 9ba59715 by Jason Merrill Committed by Jason Merrill

re PR c++/43075 (20_util/bind/ref2.cc FAILs)

	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.

From-SVN: r156842
parent 77278f4a
2010-02-17 Jason Merrill <jason@redhat.com> 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 PR c++/43069
* name-lookup.c (set_decl_namespace): Don't copy DECL_CONTEXT if the * name-lookup.c (set_decl_namespace): Don't copy DECL_CONTEXT if the
decl we looked up doesn't match. decl we looked up doesn't match.
......
...@@ -5782,8 +5782,20 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) ...@@ -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, tree to = stabilize_reference (cp_build_indirect_ref (fa, RO_NULL,
complain)); 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; return val;
} }
} }
...@@ -5797,7 +5809,15 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) ...@@ -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 as_base = CLASSTYPE_AS_BASE (type);
tree arg = argarray[1]; 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); arg = cp_build_indirect_ref (arg, RO_NULL, complain);
val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg); val = build2 (MODIFY_EXPR, TREE_TYPE (to), to, arg);
......
...@@ -884,15 +884,6 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) ...@@ -884,15 +884,6 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
*walk_subtrees = 0; *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); pointer_set_insert (p_set, *stmt_p);
return NULL; return NULL;
......
...@@ -69,49 +69,6 @@ cxx_warn_unused_global_decl (const_tree decl) ...@@ -69,49 +69,6 @@ cxx_warn_unused_global_decl (const_tree decl)
return true; 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. */ /* Langhook for tree_size: determine size of our 'x' and 'c' nodes. */
size_t size_t
cp_tree_size (enum tree_code code) cp_tree_size (enum tree_code code)
......
...@@ -5445,7 +5445,6 @@ extern bool cp_dump_tree (void *, tree); ...@@ -5445,7 +5445,6 @@ extern bool cp_dump_tree (void *, tree);
extern alias_set_type cxx_get_alias_set (tree); extern alias_set_type cxx_get_alias_set (tree);
extern bool cxx_warn_unused_global_decl (const_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 size_t cp_tree_size (enum tree_code);
extern bool cp_var_mod_type_p (tree, tree); extern bool cp_var_mod_type_p (tree, tree);
extern void cxx_initialize_diagnostics (struct diagnostic_context *); extern void cxx_initialize_diagnostics (struct diagnostic_context *);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment