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