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