OK.
On Wed, Oct 11, 2017 at 4:54 PM, Jakub Jelinek <ja...@redhat.com> wrote: > Hi! > > Another case where we ICE because we optimize away store to bitsize 0 > addressable object from call. We can't optimize them away, otherwise > we'd try to create the temporaries again and fail to do so. > > Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for > trunk? > > 2017-10-11 Jakub Jelinek <ja...@redhat.com> > > PR c++/82159 > * expr.c (store_field): Don't optimize away bitsize == 0 store > from CALL_EXPR with addressable return type. > > * g++.dg/opt/pr82159-2.C: New test. > > --- gcc/expr.c.jj 2017-10-10 22:04:06.000000000 +0200 > +++ gcc/expr.c 2017-10-11 16:48:45.428536126 +0200 > @@ -6749,8 +6749,11 @@ store_field (rtx target, HOST_WIDE_INT b > return const0_rtx; > > /* If we have nothing to store, do nothing unless the expression has > - side-effects. */ > - if (bitsize == 0) > + side-effects. Don't do that for zero sized addressable lhs of > + calls. */ > + if (bitsize == 0 > + && (!TREE_ADDRESSABLE (TREE_TYPE (exp)) > + || TREE_CODE (exp) != CALL_EXPR)) > return expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL); > > if (GET_CODE (target) == CONCAT) > --- gcc/testsuite/g++.dg/opt/pr82159-2.C.jj 2017-10-11 17:27:18.050861346 > +0200 > +++ gcc/testsuite/g++.dg/opt/pr82159-2.C 2017-10-11 17:27:27.081753330 > +0200 > @@ -0,0 +1,65 @@ > +// PR c++/82159 > +// { dg-do compile } > +// { dg-options "" } > + > +template <typename T> struct D { T e; }; > +struct F : D<int[0]> { > + F(const F &); > +}; > +struct G : F { > + template <class T> G operator-(T); > +}; > +template <class T> struct I { > + typedef typename T::template J<I> ak; > +}; > +template <class T> struct K { typename I<T>::ak an; }; > +struct H { > + G l; > +}; > +struct C { > + ~C(); > +}; > +template <class T> struct M : T { > + template <typename U, typename V> M(U, V); > + H h; > + virtual void foo() { T::bar(&h); } > +}; > +template <int, typename> class A; > +template <class> struct B { > + typedef int BT; > + struct BC {}; > + template <class T> struct BD { > + G g; > + BD(BT, T n) : g(n.l - 0) {} > + }; > + B(BT, BC); > +}; > +template <typename> struct O; > +template <int T, typename U> > +struct O<B<A<T, U> > > : public B<A<T, U> >::BC {}; > +struct L : B<A<2, double> > { > + struct P : C { > + void bar(H *x) { > + BT a; > + BD<H>(a, *x); > + } > + }; > + template <typename U, typename V> L(U x, V n) : B(x, n) {} > + int ll; > + virtual int baz() { M<P>(this, ll); } > +}; > +template <typename> class Q { > + O<B<A<2, double> > > q; > + virtual L baz() { L(0, q); } > +}; > +template <template <class> class T> struct R { > + R() { T<int>(); } > +}; > +struct S { > + template <class> class J : R<Q> {}; > +}; > +void foo() { K<S> c; } > + > +int main() { > + return 0; > +} > > Jakub