aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2014-07-10 17:48:26 -0400
committerJason Merrill <jason@gcc.gnu.org>2014-07-10 17:48:26 -0400
commita25b76d802c2df2b082b874f242d089d1a2bb42a (patch)
treee79e24ee8695c67cc2b32aeed871c60d77c78af4 /gcc
parentc0221884ecbda8d99a43aa0f5e306638c71533d6 (diff)
downloadgcc-a25b76d802c2df2b082b874f242d089d1a2bb42a.zip
gcc-a25b76d802c2df2b082b874f242d089d1a2bb42a.tar.gz
gcc-a25b76d802c2df2b082b874f242d089d1a2bb42a.tar.bz2
re PR c++/61661 (Bogus error: ‘const Outer::Foo{&Outer::Bar}’ is not a constant expression)
PR c++/61661 * semantics.c (reduced_constant_expression_p): Handle CONSTRUCTOR. From-SVN: r212439
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog3
-rw-r--r--gcc/cp/semantics.c23
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem2.C13
3 files changed, 34 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a184a40..ef04cba 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
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 };
+};