https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84378
Bug ID: 84378 Summary: Misleading diagnostics when using ambiguous names for ptr to memfun args in member fn Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: petschy at gmail dot com Target Milestone: --- Created attachment 43414 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43414&action=edit source to reproduce the bug An enum member and a using typedef clashes. When defining a member function pointer, GCC gives the correct reason if it is defined in a free standing function, however, the reasoning is omitted if it is defined in a class member function. Tried with 7.3.1, 8.0.0 and 8.0.1, all the same. In both cases there is some misleading 'noise' in the diagnostics. Errors for the free standing function: 20180214-pmf.cpp: In function ‘void foo()’: 20180214-pmf.cpp:25:19: error: cannot declare pointer to ‘void’ member void(Bar::*mfpf)(MyFoo, bool, const char*); ^~~~~ There is NO 'void' member. 20180214-pmf.cpp:25:19: error: reference to ‘MyFoo’ is ambiguous 20180214-pmf.cpp:19:19: note: candidates are: ‘Enum MyFoo’ enum Enum : int { MyFoo, MyBar, MyBaz }; ^~~~~ 20180214-pmf.cpp:9:44: note: ‘using MyFoo = struct ns1::Foo<int, ns2::MyFooTag>’ using MyFoo = ns1::Foo<int, class MyFooTag>; ^ This is all I needed! 20180214-pmf.cpp:25:26: error: expected primary-expression before ‘bool’ void(Bar::*mfpf)(MyFoo, bool, const char*); ^~~~ 20180214-pmf.cpp:25:32: error: expected primary-expression before ‘const’ void(Bar::*mfpf)(MyFoo, bool, const char*); ^~~~~ 20180214-pmf.cpp:25:43: error: expression list treated as compound expression in initializer [-fpermissive] void(Bar::*mfpf)(MyFoo, bool, const char*); ^ 20180214-pmf.cpp:27:15: error: cannot convert ‘void (Bar::*)(ns2::MyFoo, bool, const char*)’ {aka ‘void (Bar::*)(ns1::Foo<int, ns2::MyFooTag>, bool, const char*)’} to ‘void Bar::*’ in assignment mfpf = &Bar::Baz; ^~~ This isn't too helpful, either. Errors for the member function. The most helpful message about the ambiguity is omitted, unfortunately: 20180214-pmf.cpp: In member function ‘void Class::MemFun()’: 20180214-pmf.cpp:38:20: error: cannot declare pointer to ‘void’ member void(Bar::*mfpf)(MyFoo2, bool, const char*); ^~~~~~ 20180214-pmf.cpp:38:28: error: expected primary-expression before ‘bool’ void(Bar::*mfpf)(MyFoo2, bool, const char*); ^~~~ 20180214-pmf.cpp:38:34: error: expected primary-expression before ‘const’ void(Bar::*mfpf)(MyFoo2, bool, const char*); ^~~~~ 20180214-pmf.cpp:38:45: error: expression list treated as compound expression in initializer [-fpermissive] void(Bar::*mfpf)(MyFoo2, bool, const char*); ^ 20180214-pmf.cpp:40:16: error: cannot convert ‘void (Bar::*)(ns2::MyFoo2, bool, const char*)’ {aka ‘void (Bar::*)(ns1::Foo<int, ns2::MyFoo2Tag>, bool, const char*)’} to ‘void Bar::*’ in assignment mfpf = &Bar::Baz2; ^~~~ $ g++-7.3.1 -v Using built-in specs. COLLECT_GCC=g++-7.3.1 COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-pc-linux-gnu/7.3.1/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../configure --enable-languages=c,c++ --disable-multilib --program-suffix=-7.3.1 --disable-bootstrap CFLAGS='-O2 -march=native' CXXFLAGS='-O2 -march=native' Thread model: posix gcc version 7.3.1 20180214 (GCC) $ g++-8.0.1 -v Using built-in specs. COLLECT_GCC=g++-8.0.1 COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-pc-linux-gnu/8.0.1/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../configure --enable-languages=c,c++ --disable-multilib --program-suffix=-8.0.1 --disable-bootstrap CFLAGS='-O2 -march=native' CXXFLAGS='-O2 -march=native' Thread model: posix gcc version 8.0.1 20180214 (experimental) (GCC)