calls.c (expand_call): Strip a TARGET_EXPR if we're passing by invisible reference.
authorJason Merrill <jason@yorick.cygnus.com>
Tue, 19 Jan 1999 11:55:37 +0000 (11:55 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 19 Jan 1999 11:55:37 +0000 (06:55 -0500)
* calls.c (expand_call): Strip a TARGET_EXPR if we're passing by
invisible reference.

From-SVN: r24763

gcc/ChangeLog
gcc/calls.c

index a8f8ecb355412634a6361d8518d528bf1c558752..b9ca3b78a8028076a60ac3c931fc82a469d6f249 100644 (file)
@@ -1,3 +1,8 @@
+Tue Jan 19 11:54:04 1999  Jason Merrill  <jason@yorick.cygnus.com>
+
+       * calls.c (expand_call): Strip a TARGET_EXPR if we're passing by
+       invisible reference.
+
 Tue Jan 19 14:51:36 1999  David Edelsohn  <edelsohn@mhpcc.edu>
 
        * rs6000.c (offsettable_addr_operand): Delete.
index 751e9a5b8a09631f323e820bd8cf3971a13c2765..8ce140aeebcf32203ec66a9696387b3e2f8159f6 100644 (file)
@@ -1345,6 +1345,22 @@ expand_call (exp, target, ignore)
 #endif
              )
            {
+             /* C++ uses a TARGET_EXPR to indicate that we want to make a
+                new object from the argument.  If we are passing by
+                invisible reference, the callee will do that for us, so we
+                can strip off the TARGET_EXPR.  This is not always safe,
+                but it is safe in the only case where this is a useful
+                optimization; namely, when the argument is a plain object.
+                In that case, the frontend is just asking the backend to
+                make a bitwise copy of the argument. */
+                
+             if (TREE_CODE (args[i].tree_value) == TARGET_EXPR
+                 && (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND
+                                                 (args[i].tree_value, 1)))
+                     == 'd')
+                 && ! REG_P (DECL_RTL (TREE_OPERAND (args[i].tree_value, 1))))
+               args[i].tree_value = TREE_OPERAND (args[i].tree_value, 1);
+
              args[i].tree_value = build1 (ADDR_EXPR,
                                           build_pointer_type (type),
                                           args[i].tree_value);