On Tue, Feb 05, 2019 at 11:16:04AM -0500, Jason Merrill wrote: > > --- gcc/cp/optimize.c.jj 2019-01-21 23:32:43.000000000 +0100 > > +++ gcc/cp/optimize.c 2019-02-04 16:40:21.354179933 +0100 > > @@ -417,6 +417,12 @@ maybe_thunk_body (tree fn, bool force) > > gcc_assert (clone_parm); > > DECL_ABSTRACT_ORIGIN (clone_parm) = NULL; > > args[parmno] = clone_parm; > > + /* Clear TREE_ADDRESSABLE on arguments with non-aggregate > > + types, the thunk will not take addresses of those > > + arguments, will just pass them through to another > > + call. */ > > + if (!AGGREGATE_TYPE_P (TREE_TYPE (clone_parm))) > > + TREE_ADDRESSABLE (clone_parm) = 0; > > We probably want to do this in maybe_add_lambda_conv_op, as well (in the > loop over fn_args that sets DECL_CONTEXT).
Like below? > I notice that use_thunk clears TREE_ADDRESSABLE unconditionally, is it > important to handle aggregates differently here? No, I was just trying to be too careful. If use_thunk does that unconditionally, I think we can as well. > use_thunk also clears DECL_RTL and DECL_HAS_VALUE_EXPR_P, I don't know if > that's important. I can't imagine how DECL_RTL could be set (these days) and have no idea why DECL_VALUE_EXPR would be used either. I'll bootstrap/regtest following patch then: 2019-02-05 Jakub Jelinek <[email protected]> PR c++/89187 * optimize.c (maybe_thunk_body): Clear TREE_ADDRESSABLE on PARM_DECLs of the thunk. * lambda.c (maybe_add_lambda_conv_op): Likewise. * g++.dg/opt/pr89187.C: New test. --- gcc/cp/optimize.c.jj 2019-02-05 10:04:17.089060672 +0100 +++ gcc/cp/optimize.c 2019-02-05 17:34:37.644762690 +0100 @@ -417,6 +417,8 @@ maybe_thunk_body (tree fn, bool force) gcc_assert (clone_parm); DECL_ABSTRACT_ORIGIN (clone_parm) = NULL; args[parmno] = clone_parm; + /* Clear TREE_ADDRESSABLE on thunk arguments. */ + TREE_ADDRESSABLE (clone_parm) = 0; clone_parm = TREE_CHAIN (clone_parm); } if (fn_parm_typelist) --- gcc/cp/lambda.c.jj 2019-02-02 11:07:01.217345765 +0100 +++ gcc/cp/lambda.c 2019-02-05 17:37:00.573387272 +0100 @@ -1130,6 +1130,9 @@ maybe_add_lambda_conv_op (tree type) { tree new_node = copy_node (src); + /* Clear TREE_ADDRESSABLE on thunk arguments. */ + TREE_ADDRESSABLE (new_node) = 0; + if (!fn_args) fn_args = tgt = new_node; else --- gcc/testsuite/g++.dg/opt/pr89187.C.jj 2019-02-05 17:33:44.230650417 +0100 +++ gcc/testsuite/g++.dg/opt/pr89187.C 2019-02-05 17:33:44.230650417 +0100 @@ -0,0 +1,23 @@ +// PR c++/89187 +// { dg-do compile { target c++11 } } +// { dg-options "-Os -fno-tree-ccp -fno-tree-sra -fno-inline" } + +template <typename T, int N> struct A { + typedef T __attribute__((vector_size (N))) type; +}; +template <typename T, int N> using B = typename A<T, N>::type; +template <typename T> using C = B<T, 4>; +struct D { + D (C<int> x) : d{x[3]} {} + D foo () { return d; } + C<int> d; +}; +extern D d; +struct { D bar () { return d; } } l; +struct E { void baz () const; }; + +void +E::baz () const +{ + l.bar ().foo (); +} Jakub
