re PR c++/43075 (20_util/bind/ref2.cc FAILs)
authorJason Merrill <jason@redhat.com>
Wed, 17 Feb 2010 22:51:51 +0000 (17:51 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 17 Feb 2010 22:51:51 +0000 (17:51 -0500)
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

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-gimplify.c
gcc/cp/cp-objcp-common.c
gcc/cp/cp-tree.h

index ef12985..9ebc609 100644 (file)
@@ -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.
index 54254c3..5e66c62 100644 (file)
@@ -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);
index df09b60..533d2d1 100644 (file)
@@ -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;
index f06ad5b..460f32f 100644 (file)
@@ -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)
index f32c6e8..b5330a3 100644 (file)
@@ -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 *);