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  <ja...@redhat.com>

        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

Reply via email to