On Mon, Apr 10, 2017 at 08:41:28AM -0400, Nathan Sidwell wrote: > On 04/10/2017 08:18 AM, Jakub Jelinek wrote: > > Hi! > > > > I'd like to ping 2 patches: > > > > P2 PR c++/80176 > > http://gcc.gnu.org/ml/gcc-patches/2017-04/msg00027.html > > reference binding to static member function > > This smells fishy. There's no reason one cannot have an overload set > containing both static and non-static functions, in any order. So it'll be > 'random' as to which member of the set OVL_CURRENT looks at.
I actually don't know if I need the OVL_CURRENT thing, maybe not. On the testcase there is an overloaded static member function and I don't get an error on that, just on the non-overloaded one. I've tried: struct X { static void foo(); static void baz(int); static int baz(double); void m(int); void n(int); int n(float); } x; 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) = x.m; void (&r9)(int) = x.n; int (&r10)(float) = x.n; and there I see COMPONENT_REF with BASELINK second operand with BASELINK_FUNCTIONS being an overload only for the methods. And even if I try overload with mixed methods and static member functions, lvalue_kind with that is only called when seeing the invalid binding to method: struct X { void o(unsigned char); static void o(int); void o(double); } x; void (&r12)(int) = x.o; void (&r13)(double) = x.o; Thus, would it be acceptable to omit the OVL_CURRENT as in (tested so far just on the updated ref23.C with additional test from the above r12 snippet, of course would perform full bootstrap/regtest with that)? 2017-04-08 Jakub Jelinek <ja...@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. --- gcc/cp/tree.c.jj 2017-04-07 21:17:57.078208891 +0200 +++ gcc/cp/tree.c 2017-04-10 15:18:57.941508441 +0200 @@ -105,6 +105,14 @@ 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. */ + 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) --- gcc/testsuite/g++.dg/init/ref23.C.jj 2017-04-10 15:17:04.823911276 +0200 +++ gcc/testsuite/g++.dg/init/ref23.C 2017-04-10 15:18:07.504133944 +0200 @@ -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; Jakub