A couple of small bugs involving pointers to member functions in
templates. In 61500, we were failing to handle MEMBER_REF in
lvalue_kind. In 61488, we were failing to handle unlowered PMF syntax
used as a template argument.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit ef46b757ccae754f3edc937acfa39bcc19e57111
Author: Jason Merrill <ja...@redhat.com>
Date: Fri Jun 13 15:01:15 2014 -0400
PR c++/61488
* pt.c (check_valid_ptrmem_cst_expr): Fix for template context.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 8858908..df57293 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -5350,6 +5350,10 @@ check_valid_ptrmem_cst_expr (tree type, tree expr,
return true;
if (cxx_dialect >= cxx11 && null_member_pointer_value_p (expr))
return true;
+ if (processing_template_decl
+ && TREE_CODE (expr) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (expr, 0)) == OFFSET_REF)
+ return true;
if (complain & tf_error)
{
error ("%qE is not a valid template argument for type %qT",
diff --git a/gcc/testsuite/g++.dg/template/ptrmem28.C b/gcc/testsuite/g++.dg/template/ptrmem28.C
new file mode 100644
index 0000000..0379960
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ptrmem28.C
@@ -0,0 +1,10 @@
+// PR c++/61488
+
+struct A {
+ typedef int (A::*cont_func)();
+ template <A::cont_func> void wait(int);
+ int notify();
+
+ void fix() { wait<&A::notify>(0); } // OK
+ template <int> void repair() { wait<&A::notify>(0); }
+};
commit 7a2deb52336c87960d6c75439978302d0facdda8
Author: jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Mon Jun 16 11:45:37 2014 +0000
PR c++/61500
* tree.c (lvalue_kind): Handle MEMBER_REF and DOTSTAR_EXPR.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@211703 138bc75d-0d04-0410-961f-82ee72b054a4
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 587ae80..3616605 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -102,6 +102,16 @@ lvalue_kind (const_tree ref)
case IMAGPART_EXPR:
return lvalue_kind (TREE_OPERAND (ref, 0));
+ case MEMBER_REF:
+ case DOTSTAR_EXPR:
+ if (TREE_CODE (ref) == MEMBER_REF)
+ op1_lvalue_kind = clk_ordinary;
+ else
+ op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0));
+ if (TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (ref, 1))))
+ op1_lvalue_kind = clk_none;
+ return op1_lvalue_kind;
+
case COMPONENT_REF:
op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0));
/* Look at the member designator. */
diff --git a/gcc/testsuite/g++.dg/template/ptrmem27.C b/gcc/testsuite/g++.dg/template/ptrmem27.C
new file mode 100644
index 0000000..8c63f9c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/ptrmem27.C
@@ -0,0 +1,22 @@
+// PR c++/61500
+
+struct X {
+ int i;
+ int j;
+
+ int foo(int X::* ptr);
+
+ template <int X::* ptr>
+ int bar();
+};
+
+int X::foo(int X::* ptr) {
+ int* p = &(this->*ptr); // OK.
+ return *p;
+}
+
+template <int X::* ptr>
+int X::bar() {
+ int* p = &(this->*ptr); // gcc 4.9.0: OK in C++98 mode, fails in C++11 mode.
+ return *p;
+}