OK, but I wonder why we don't do constant initialization of that variable...

On Wed, Nov 23, 2016 at 9:59 AM, Jakub Jelinek <ja...@redhat.com> wrote:
> Hi!
>
> During cp_fold, we see a call to constructor and because the ctor
> is DECL_DECLARED_CONSTEXPR_P, when optimizing we call maybe_constant_value
> on it.  But as when evaluating that we don't have an object, it returns
> the initializer of the var, rather than an assignment of the initializer to
> the var, so it is optimized away.
>
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk?
>
> 2016-11-23  Jakub Jelinek  <ja...@redhat.com>
>
>         PR c++/77907
>         * cp-gimplify.c (cp_fold) <case CALL_EXPR>: When calling constructor
>         and maybe_constant_value returns non-CALL_EXPR, create INIT_EXPR
>         with the object on lhs and maybe_constant_value returned expr on rhs.
>
>         * g++.dg/cpp0x/pr77907.C: New test.
>
> --- gcc/cp/cp-gimplify.c.jj     2016-11-22 21:31:41.000000000 +0100
> +++ gcc/cp/cp-gimplify.c        2016-11-23 12:42:07.803518968 +0100
> @@ -2338,11 +2338,18 @@ cp_fold (tree x)
>            constant, but the call followed by an INDIRECT_REF is.  */
>         if (callee && DECL_DECLARED_CONSTEXPR_P (callee)
>             && !flag_no_inline)
> -          r = maybe_constant_value (x);
> +         r = maybe_constant_value (x);
>         optimize = sv;
>
>          if (TREE_CODE (r) != CALL_EXPR)
>           {
> +           if (DECL_CONSTRUCTOR_P (callee))
> +             {
> +               loc = EXPR_LOCATION (x);
> +               tree s = build_fold_indirect_ref_loc (loc,
> +                                                     CALL_EXPR_ARG (x, 0));
> +               r = build2_loc (loc, INIT_EXPR, TREE_TYPE (s), s, r);
> +             }
>             x = r;
>             break;
>           }
> --- gcc/testsuite/g++.dg/cpp0x/pr77907.C.jj     2016-11-23 12:42:46.660031305 
> +0100
> +++ gcc/testsuite/g++.dg/cpp0x/pr77907.C        2016-11-23 12:40:12.000000000 
> +0100
> @@ -0,0 +1,22 @@
> +// PR c++/77907
> +// { dg-do run { target c++11 } }
> +// { dg-options "-O2" }
> +
> +struct A {
> +  int foo () { return 1; }
> +};
> +
> +struct B {
> +  using C = int (A::*) ();
> +  constexpr explicit B (const C x) : b{x} {}
> +  C b;
> +};
> +
> +B b{&A::foo};
> +
> +int
> +main ()
> +{
> +  if (!b.b)
> +    __builtin_abort ();
> +}
>
>         Jakub

Reply via email to