diff mbox

C++ PATCH for c++/61661 (constexpr and ptrmem)

Message ID 53BF0BBE.6020007@redhat.com
State New
Headers show

Commit Message

Jason Merrill July 10, 2014, 9:55 p.m. UTC
If we handle PTRMEM_CST specially, we also need to handle any 
CONSTRUCTORs that wrap them.

Tested x86_64-pc-linux-gnu, applying to trunk and 4.9.
diff mbox

Patch

commit a2f90f6d52fa4c3d5391b23914c4177c3272817c
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Jul 10 17:05:28 2014 -0400

    	PR c++/61661
    	* semantics.c (reduced_constant_expression_p): Handle CONSTRUCTOR.

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index a6f5a4a..a6d941b 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -8519,11 +8519,24 @@  cxx_eval_call_expression (const constexpr_call *old_call, tree t,
 bool
 reduced_constant_expression_p (tree t)
 {
-  if (TREE_CODE (t) == PTRMEM_CST)
-    /* Even if we can't lower this yet, it's constant.  */
-    return true;
-  /* FIXME are we calling this too much?  */
-  return initializer_constant_valid_p (t, TREE_TYPE (t)) != NULL_TREE;
+  switch (TREE_CODE (t))
+    {
+    case PTRMEM_CST:
+      /* Even if we can't lower this yet, it's constant.  */
+      return true;
+
+    case CONSTRUCTOR:
+      /* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR.  */
+      tree elt; unsigned HOST_WIDE_INT idx;
+      FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), idx, elt)
+	if (!reduced_constant_expression_p (elt))
+	  return false;
+      return true;
+
+    default:
+      /* FIXME are we calling this too much?  */
+      return initializer_constant_valid_p (t, TREE_TYPE (t)) != NULL_TREE;
+    }
 }
 
 /* Some expressions may have constant operands but are not constant
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem2.C
new file mode 100644
index 0000000..86859aa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem2.C
@@ -0,0 +1,13 @@ 
+// PR c++/61661
+// { dg-do compile { target c++11 } }
+
+struct Outer {
+
+  void Bar();
+
+  struct Foo {
+    void (Outer::*ptr)() ;
+  };
+
+  static constexpr Foo foo = { &Outer::Bar };
+};