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