re PR c++/61661 (Bogus error: ‘const Outer::Foo{&Outer::Bar}’ is not a constant expre...
authorJason Merrill <jason@redhat.com>
Thu, 10 Jul 2014 21:48:26 +0000 (17:48 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 10 Jul 2014 21:48:26 +0000 (17:48 -0400)
PR c++/61661
* semantics.c (reduced_constant_expression_p): Handle CONSTRUCTOR.

From-SVN: r212439

gcc/cp/ChangeLog
gcc/cp/semantics.c
gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem2.C [new file with mode: 0644]

index a184a401d9f289c8084d7e8cfbb5e9d4527cc4cd..ef04cba5cea6a9951feff32dd5103afbe266f110 100644 (file)
@@ -1,5 +1,8 @@
 2014-07-10  Jason Merrill  <jason@redhat.com>
 
+       PR c++/61661
+       * semantics.c (reduced_constant_expression_p): Handle CONSTRUCTOR.
+
        PR c++/61659
        PR c++/61687
        * decl2.c (mark_all_virtuals): New variable.
index a6f5a4a413c32dfddbb7cd42ed92510283987e13..a6d941b5532cd0fa9b9c0393596e4d640a220ef9 100644 (file)
@@ -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 (file)
index 0000000..86859aa
--- /dev/null
@@ -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 };
+};