adjust_temp_type was wrapping a PTRMEM_CST in a NOP_EXPR, which confused
constexpr evaluation. We can avoid this by fixing cp_fold_convert to
properly fold away the conversion.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit a5a7219fc54d6d724a032befea810910cda01fc7
Author: Jason Merrill <ja...@redhat.com>
Date: Sat Apr 11 10:57:07 2015 -0400
PR c++/65695
* cvt.c (cp_fold_convert): Avoid wrapping PTRMEM_CST in NOP_EXPR.
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index d0924f1..9aa9006 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 0000000..68788ca
--- /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;