]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR c++/80176 (cannot bind reference to static member function using...
authorJakub Jelinek <jakub@redhat.com>
Tue, 30 May 2017 08:24:21 +0000 (10:24 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 30 May 2017 08:24:21 +0000 (10:24 +0200)
Backported from mainline
2017-04-10  Jakub Jelinek  <jakub@redhat.com>

PR c++/80176
* tree.c (lvalue_kind): For COMPONENT_REF with BASELINK second
operand, if it is a static member function, recurse on the
BASELINK.

* g++.dg/init/ref23.C: New test.

From-SVN: r248669

gcc/cp/ChangeLog
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/init/ref23.C [new file with mode: 0644]

index d867b9c5f9faef199a6164a4a79b42a877163f86..1bd0d7cd486131cba3034afa0efcf93e5d51ba25 100644 (file)
@@ -1,6 +1,13 @@
 2017-05-30  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2017-04-10  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/80176
+       * tree.c (lvalue_kind): For COMPONENT_REF with BASELINK second
+       operand, if it is a static member function, recurse on the
+       BASELINK.
+
        2017-03-22  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/80141
index 4a7008b5a233ee0dba39153d05a28c6be3816d7d..6b145c40759402a8ef637a1ebee6ff95dd0b9cb5 100644 (file)
@@ -129,6 +129,17 @@ lvalue_kind (const_tree ref)
       return op1_lvalue_kind;
 
     case COMPONENT_REF:
+      if (BASELINK_P (TREE_OPERAND (ref, 1)))
+       {
+         tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (ref, 1));
+
+         /* For static member function recurse on the BASELINK, we can get
+            here e.g. from reference_binding.  If BASELINK_FUNCTIONS is
+            OVERLOAD, the overload is resolved first if possible through
+            resolve_address_of_overloaded_function.  */
+         if (TREE_CODE (fn) == FUNCTION_DECL && DECL_STATIC_FUNCTION_P (fn))
+           return lvalue_kind (TREE_OPERAND (ref, 1));
+       }
       op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0));
       /* Look at the member designator.  */
       if (!op1_lvalue_kind)
index 771cf18547dc19c0b43afdb9962c138a5d1d13b5..d6179039f1a99f5b434520ba1777cc8d26941c05 100644 (file)
@@ -1,6 +1,11 @@
 2017-05-30  Jakub Jelinek  <jakub@redhat.com>
 
        Backported from mainline
+       2017-04-10  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/80176
+       * g++.dg/init/ref23.C: New test.
+
        2017-04-04  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/80286
diff --git a/gcc/testsuite/g++.dg/init/ref23.C b/gcc/testsuite/g++.dg/init/ref23.C
new file mode 100644 (file)
index 0000000..12b8851
--- /dev/null
@@ -0,0 +1,15 @@
+// PR c++/80176
+// { dg-do compile }
+
+struct X { static void foo(); static void baz(int); static int baz(double); } x;
+struct Y { void o(unsigned char); static void o(int); void o(double); } y;
+void X::foo() {}
+static void bar() {}
+void (&r1)() = x.foo;
+void (&r2)() = X::foo;
+void (&r3)() = bar;
+void (&r4)(int) = x.baz;
+int (&r5)(double) = x.baz;
+void (&r6)(int) = X::baz;
+int (&r7)(double) = X::baz;
+void (&r8)(int) = y.o;