From a25b76d802c2df2b082b874f242d089d1a2bb42a Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 10 Jul 2014 17:48:26 -0400 Subject: [PATCH] =?UTF-8?q?re=20PR=20c++/61661=20(Bogus=20error:=20?= =?UTF-8?q?=E2=80=98const=20Outer::Foo{&Outer::Bar}=E2=80=99=20is=20not=20?= =?UTF-8?q?a=20constant=20expression)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR c++/61661 * semantics.c (reduced_constant_expression_p): Handle CONSTRUCTOR. From-SVN: r212439 --- gcc/cp/ChangeLog | 3 +++ gcc/cp/semantics.c | 23 +++++++++++++++---- .../g++.dg/cpp0x/constexpr-ptrmem2.C | 13 +++++++++++ 3 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a184a401d9f..ef04cba5cea 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2014-07-10 Jason Merrill + 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 a6f5a4a413c..a6d941b5532 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 00000000000..86859aa12bc --- /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 }; +};