https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90501
--- Comment #13 from rguenther at suse dot de <rguenther at suse dot de> --- On Thu, 16 May 2019, ibuclaw at gdcproject dot org wrote: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90501 > > --- Comment #11 from Iain Buclaw <ibuclaw at gdcproject dot org> --- > (In reply to Jakub Jelinek from comment #8) > > So the first question would be why D passes the return value as > > DECL_BY_REFERENCE if it doesn't have TREE_ADDRESSABLE type. > > Looking at the places where DECL_BY_REFERENCE is set, this mismatch could > happen when the result should be returned using NRVO. > > To memory, using a mixture of DECL_BY_REFERENCE and CALL_EXPR_RETURN_SLOT_OPT > gives a desired behaviour of eliding a copy. > > Two things come to mind as alternatives: > > 1. Currently for NRVO, the DECL_RESULT is explicitly set as not addressable. > > TREE_TYPE (resdecl) = build_reference_type (TREE_TYPE (resdecl)); > DECL_BY_REFERENCE (resdecl) = 1; > TREE_ADDRESSABLE (resdecl) = 0; > > Is it allowed for the decl to be both DECL_BY_REFERENCE and TREE_ADDRESSABLE > at > the same time? Or will that just confuse things further. I think that's independent - iff DECL_BY_REFERENCE then resdecl is the pointer to the decl, so whether the pointer has its address taken isn't known here yet. > TREE_TYPE (resdecl) = build_reference_type (TREE_TYPE (resdecl)); > DECL_BY_REFERENCE (resdecl) = 1; > - TREE_ADDRESSABLE (resdecl) = 0; > + if (TREE_ADDRESSABLE (TREE_TYPE (resdecl)) > + TREE_ADDRESSABLE (resdecl) = 0; > > > 2. Redo handling of NRVO in the D front-end, to enforce a specific semantic > for > trivial types that we want to elide a copy for. > > i.e: Given, > --- > S foo() > { > S result; > result.a = 3; > return result; > } > > void test() > { > S s = foo(); > } > --- > > Generate this explicitly as: > --- > S* foo(S* hidden) > { > S result; > result.a = 3; > *hidden = result; > return hidden; > } > > void test() > { > S tmp; > S s = *foo(&tmp); > } > --- > > Obviously, that change would be a bit more involved on my side. I don't think this would be FE friendly design of the middle-end. Thus my question would be why we do have the special-casing of TREE_ADDRESSABLE (TREE_TYPE (..)) on DECL_BY_REFERENCE decls. That is, why's Index: gcc/gimple-walk.c =================================================================== --- gcc/gimple-walk.c (revision 271394) +++ gcc/gimple-walk.c (working copy) @@ -829,8 +829,7 @@ walk_stmt_load_store_addr_ops (gimple *s gimple_call_chain (call_stmt), data); if (visit_addr && gimple_call_return_slot_opt_p (call_stmt) - && gimple_call_lhs (call_stmt) != NULL_TREE - && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (call_stmt)))) + && gimple_call_lhs (call_stmt) != NULL_TREE) ret |= visit_addr (stmt, gimple_call_lhs (call_stmt), gimple_call_lhs (call_stmt), data); } not correct? Do we really force a new temporary to be used? We'd need to be consistent here for inlining as well then.