aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2016-11-23 19:45:27 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2016-11-23 19:45:27 +0100
commit25cb6b33f75fb4183bfe816cf95b68613b1af4bb (patch)
treef23f1000b81157a0be8bdb134f4e00fb059a5c2a
parent6103184e81c0b6a8b1f4e072e0c32d9bb86fcc15 (diff)
downloadgcc-25cb6b33f75fb4183bfe816cf95b68613b1af4bb.zip
gcc-25cb6b33f75fb4183bfe816cf95b68613b1af4bb.tar.gz
gcc-25cb6b33f75fb4183bfe816cf95b68613b1af4bb.tar.bz2
re PR c++/77907 (Add "const" to argument of constexpr constructor causes the object to be left in unconstructed state)
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. From-SVN: r242790
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/cp-gimplify.c9
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr77907.C22
4 files changed, 40 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 7418b22..1386d4ef 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,10 @@
2016-11-23 Jakub Jelinek <jakub@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.
+
PR c++/71450
* pt.c (tsubst_copy): Return error_mark_node when mark_used
fails, even when complain & tf_error.
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 0b8f9fc..0678243 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -2340,11 +2340,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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 084f366..c74a422 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2016-11-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/77907
+ * g++.dg/cpp0x/pr77907.C: New test.
+
2016-11-23 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
PR middle-end/78153
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr77907.C b/gcc/testsuite/g++.dg/cpp0x/pr77907.C
new file mode 100644
index 0000000..d46c707
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr77907.C
@@ -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 ();
+}