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

Reply via email to