From fb899e32c16088cad1a19a3e8df615ecfd1332db Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Tue, 14 Apr 2015 12:02:41 -0400 Subject: [PATCH] re PR c++/65695 (NSDMI calling constexpr constructor with pointer-to-member is not a constant expression) PR c++/65695 * cvt.c (cp_fold_convert): Avoid wrapping PTRMEM_CST in NOP_EXPR. From-SVN: r222097 --- gcc/cp/ChangeLog | 3 +++ gcc/cp/cvt.c | 16 ++++++++++-- .../g++.dg/cpp0x/constexpr-ptrmem4.C | 26 +++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem4.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 03f6f2a4226..3b166a76078 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2015-04-14 Jason Merrill + PR c++/65695 + * cvt.c (cp_fold_convert): Avoid wrapping PTRMEM_CST in NOP_EXPR. + PR c++/65721 * name-lookup.c (do_class_using_decl): Complain about specifying the current class even if there are dependent bases. diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index d0924f100c5..9aa9006f192 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -603,8 +603,20 @@ ignore_overflows (tree expr, tree orig) tree cp_fold_convert (tree type, tree expr) { - tree conv = fold_convert (type, expr); - conv = ignore_overflows (conv, expr); + tree conv; + if (TREE_TYPE (expr) == type) + conv = expr; + else if (TREE_CODE (expr) == PTRMEM_CST) + { + /* Avoid wrapping a PTRMEM_CST in NOP_EXPR. */ + conv = copy_node (expr); + TREE_TYPE (conv) = type; + } + else + { + conv = fold_convert (type, expr); + conv = ignore_overflows (conv, expr); + } return conv; } diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem4.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem4.C new file mode 100644 index 00000000000..68788caddd2 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ptrmem4.C @@ -0,0 +1,26 @@ +// PR c++/65695 +// { dg-do compile { target c++11 } } + +struct Foo; + +struct Bar +{ + using MemberFuncT = int (Foo::*)(); + + MemberFuncT h_; + constexpr Bar(MemberFuncT h) : h_{h} + { + } +}; + +struct Foo +{ + int test() + { + return -1; + } + + static constexpr Bar bar {&Foo::test}; +}; + +constexpr Bar Foo::bar; -- 2.30.2