OK.
On Tue, Feb 21, 2017 at 8:44 AM, Jakub Jelinek <ja...@redhat.com> wrote: > Hi! > > Apparently we can end up trying to store into a pointer-to-member > that has a PTRMEM_CST as its current value. Later code in > cxx_eval_store_expression is upset that it isn't a CONSTRUCTOR when > the type is actually aggregate. > > The following patch fixes that, bootstrapped/regtested on x86_64-linux > and i686-linux, though I admit I'm not really sure if this is the best fix. > > 2017-02-21 Jakub Jelinek <ja...@redhat.com> > > PR c++/79639 > * constexpr.c (cxx_eval_store_expression): If *valp is a PTRMEM_CST, > call cplus_expand_constant on it first. > > * g++.dg/cpp1y/constexpr-79639.C: New test. > > --- gcc/cp/constexpr.c.jj 2017-02-21 13:49:06.000000000 +0100 > +++ gcc/cp/constexpr.c 2017-02-21 14:57:30.290440638 +0100 > @@ -3518,11 +3518,12 @@ cxx_eval_store_expression (const constex > wants to modify it. */ > if (*valp == NULL_TREE) > { > - *valp = new_ctx.ctor = build_constructor (type, NULL); > - CONSTRUCTOR_NO_IMPLICIT_ZERO (new_ctx.ctor) = no_zero_init; > + *valp = build_constructor (type, NULL); > + CONSTRUCTOR_NO_IMPLICIT_ZERO (*valp) = no_zero_init; > } > - else > - new_ctx.ctor = *valp; > + else if (TREE_CODE (*valp) == PTRMEM_CST) > + *valp = cplus_expand_constant (*valp); > + new_ctx.ctor = *valp; > new_ctx.object = target; > } > > --- gcc/testsuite/g++.dg/cpp1y/constexpr-79639.C.jj 2017-02-21 > 15:06:42.625475572 +0100 > +++ gcc/testsuite/g++.dg/cpp1y/constexpr-79639.C 2017-02-21 > 15:06:07.000000000 +0100 > @@ -0,0 +1,27 @@ > +// PR c++/79639 > +// { dg-do compile { target c++14 } } > + > +struct A > +{ > + void foo () {} > + void bar () {} > +}; > +typedef void (A::*T) (); > + > +constexpr T > +foo (T f) > +{ > + f = 0; > + return f; > +} > + > +constexpr T > +bar (T f) > +{ > + f = &A::bar; > + return f; > +} > + > +constexpr T a = foo (&A::foo); > +constexpr T b = foo (&A::foo); > +static_assert (a == nullptr, ""); > > Jakub