https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113075
Bug ID: 113075 Summary: Inconsistent/wrong diagnostic when incorrectly taking address of single/overloaded Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: waffl3x at protonmail dot com Target Milestone: --- I am including all 3 bugs in a single report as they are similar and located in the same region of code. ``` struct S { void f() {} void g() {} void g(int) {} void test() { void (S::*fp)() = &f; void (S::*gp)() = &g; } }; ``` <source>: In member function 'void S::test()': <source>:29:24: error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say '&S::f' [-fpermissive] 29 | void (S::*fp)() = &f; | ^ <source>:30:24: error: assuming pointer to member 'void S::g()' [-fpermissive] 30 | void (S::*gp)() = &g; | ^ <source>:30:24: note: (a pointer to member can only be formed with '&S::g') The error message between the overloaded case and the single case is largely different. Perhaps there is a reason why it should be different but this is kind of confusing in my opinion. ``` struct S { void f() {} void g() {} void g(int) {} }; int main() { S s{}; void (S::*fp)() = &s.f; void (S::*gp)() = &s.g; } ``` <source>: In function 'int main()': <source>:32:24: error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say '&S::f' [-fpermissive] 32 | void (S::*fp)() = &s.f; | ~~^ <source>:33:24: error: assuming pointer to member 'void S::g()' [-fpermissive] 33 | void (S::*gp)() = &s.g; | ^ <source>:33:24: note: (a pointer to member can only be formed with '&S::g') The single function case has a slightly different message, while the overloaded case has an identical message. This appears to be due to a lack of context in resolve_address_of_overloaded_function where the errors are emitted in the overloaded case. ``` struct B { void f() {} void g() {} void g(int) {} }; struct D : B { void test() { void (D::*fp)() = &f; void (D::*gp)() = &g; } }; ``` <source>: In member function 'void D::test()': <source>:10:24: error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say '&D::f' [-fpermissive] 10 | void (D::*fp)() = &f; | ^ <source>:11:24: error: assuming pointer to member 'void B::g()' [-fpermissive] 11 | void (D::*gp)() = &g; | ^ <source>:11:24: note: (a pointer to member can only be formed with '&B::g') The single function case properly suggests &D::f but the overload case suggests &B::g instead. All 3 bugs are super mild, and I don't know how feasible they are to fix, but at the very least it's worth tracking them in my opinion.