aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/tree.c11
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/init/ref23.C15
4 files changed, 38 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 0a19eaa..b7cbca5 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+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-04-10 Marek Polacek <polacek@redhat.com>
PR sanitizer/80348
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 9939135..acb9b8e 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -105,6 +105,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)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b0228bd..746150b 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2017-04-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/80176
+ * g++.dg/init/ref23.C: New test.
+
2017-04-10 Thomas Koenig <tkoenig@gcc.gnu.org>
PR tree-optimization/80304
diff --git a/gcc/testsuite/g++.dg/init/ref23.C b/gcc/testsuite/g++.dg/init/ref23.C
new file mode 100644
index 0000000..12b8851
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/ref23.C
@@ -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;