From 60409070a6daca63bbb2be39cefe8692e96ad952 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 19 Jan 1999 11:55:37 +0000 Subject: [PATCH] calls.c (expand_call): Strip a TARGET_EXPR if we're passing by invisible reference. * calls.c (expand_call): Strip a TARGET_EXPR if we're passing by invisible reference. From-SVN: r24763 --- gcc/ChangeLog | 5 +++++ gcc/calls.c | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a8f8ecb3554..b9ca3b78a80 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +Tue Jan 19 11:54:04 1999 Jason Merrill + + * calls.c (expand_call): Strip a TARGET_EXPR if we're passing by + invisible reference. + Tue Jan 19 14:51:36 1999 David Edelsohn * rs6000.c (offsettable_addr_operand): Delete. diff --git a/gcc/calls.c b/gcc/calls.c index 751e9a5b8a0..8ce140aeebc 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -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); -- 2.30.2