[Bug c++/50462] poor diagnostics for missing parenthesis in call to method
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50462 --- Comment #7 from Jonathan Wakely --- Oh, it's the overloaded function thjat makes the difference between saying "invalid use of non-static member function" and trying to do overload resolution with an . Reduced example that actually reproduces the original problem: struct ostream { }; void operator<<(ostream, int) { } void operator<<(ostream, void*) { } void operator<<(ostream, char*) { } struct V { int size() { return 0; }; int size() const { return 0; }; }; void print(V v) { ostream() << v.size; } Which prints this with current trunk: 50462.C: In function 'void print(V)': 50462.C:14:13: error: no match for 'operator<<' (operand types are 'ostream' and '') 14 | { ostream() << v.size; } | ~ ^~ ~~ | | | | ostream 50462.C:3:6: note: candidate: 'void operator<<(ostream, int)' 3 | void operator<<(ostream, int) { } | ^~~~ 50462.C:3:26: note: no known conversion for argument 2 from '' to 'int' 3 | void operator<<(ostream, int) { } | ^~~ 50462.C:4:6: note: candidate: 'void operator<<(ostream, void*)' 4 | void operator<<(ostream, void*) { } | ^~~~ 50462.C:4:26: note: no known conversion for argument 2 from '' to 'void*' 4 | void operator<<(ostream, void*) { } | ^ 50462.C:5:6: note: candidate: 'void operator<<(ostream, char*)' 5 | void operator<<(ostream, char*) { } | ^~~~ 50462.C:5:26: note: no known conversion for argument 2 from '' to 'char*' 5 | void operator<<(ostream, char*) { } | ^ I don't see why we should treat v.size any differently whether it's overloaded or not. It's invalid either way, so we should fail similarly.
[Bug c++/50462] poor diagnostics for missing parenthesis in call to method
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50462 --- Comment #6 from Jonathan Wakely --- (In reply to Jonathan Wakely from comment #5) > Since GCC 4.9 we don't perform overload resolution, so I think this is fixed: Huh, that's true for the reduced example in comment 4, but the original one from Chris still prints a wall of errors.
[Bug c++/50462] poor diagnostics for missing parenthesis in call to method
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50462 --- Comment #5 from Jonathan Wakely --- Since GCC 4.9 we don't perform overload resolution, so I think this is fixed: 50462.C: In function 'void print(V)': 50462.C:13:13: error: invalid use of non-static member function 'int V::size()' 13 | { ostream() << v.size; } | ~~^ 50462.C:9:13: note: declared here 9 | int size() { return 0; }; | ^~~~
[Bug c++/50462] poor diagnostics for missing parenthesis in call to method
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50462 --- Comment #4 from Jonathan Wakely --- I think the original example in this bug is the same as PR 77711 comment 2. It can be reduced to: struct ostream { }; void operator<<(ostream, int) { } void operator<<(ostream, void*) { } void operator<<(ostream, char*) { } struct V { int size() { return 0; }; }; void print(V v) { ostream() << v.size; } Now GCC's output fits on a single page: 50462.cc: In function 'void print(V)': 50462.cc:14:13: error: no match for 'operator<<' (operand types are 'ostream' and '') { ostream() << v.size; } ~~^ 50462.cc:3:6: note: candidate: void operator<<(ostream, int) void operator<<(ostream, int) { } ^~~~ 50462.cc:3:6: note: no known conversion for argument 2 from '' to 'int' 50462.cc:4:6: note: candidate: void operator<<(ostream, void*) void operator<<(ostream, void*) { } ^~~~ 50462.cc:4:6: note: no known conversion for argument 2 from '' to 'void*' 50462.cc:5:6: note: candidate: void operator<<(ostream, char*) void operator<<(ostream, char*) { } ^~~~ 50462.cc:5:6: note: no known conversion for argument 2 from '' to 'char*' But Clang still does better, not bothering to perform overload resolution hoping v.size will turn into something meaningful. Clang just says: 50462.cc:10:18: error: reference to non-static member function must be called; did you mean to call it with no arguments? { std::cout << v.size; } ~~^~~~ () 50462.cc:5:6: note: possible target for call int size() {}; ^ 50462.cc:6:6: note: possible target for call int size() const {}; ^ 1 error generated. So it doesn't bother telling us that every overload of operator<< is unusable for a nonsense expression, which is much better. EDG says: "50462.cc", line 14: error: a pointer to a bound function may only be used to call the function { ostream() << v.size; } ^ 1 error detected in the compilation of "50462.cc". This is a little cryptic and suggests there might be some non-standard extension confusing matters.
[Bug c++/50462] poor diagnostics for missing parenthesis in call to method
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50462 Jonathan Wakely changed: What|Removed |Added See Also||https://gcc.gnu.org/bugzill ||a/show_bug.cgi?id=77711 --- Comment #3 from Jonathan Wakely --- See PR 77711 comment 1 where I said: >It's irrelevant that we can't resolve which overload to use, once name lookup >finds that 'foo' is a function then a.foo is not a valid expression under any >circumstances. The same applies here. The expression 'v.size' (when not followed by parentheses) is not valid C++. Instead of trying to resolve which operator<< can be used for a nonsense expression we should just give an error immediately after parsing v.size, which is what Clang does: 50462.cc:10:18: error: reference to non-static member function must be called; did you mean to call it with no arguments? { std::cout << v.size; } ~~^~~~ () 50462.cc:5:6: note: possible target for call int size() {}; ^ 50462.cc:6:6: note: possible target for call int size() const {}; ^ 1 error generated.
[Bug c++/50462] poor diagnostics for missing parenthesis in call to method
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50462 Paolo Carlini changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2015-03-25 Ever confirmed|0 |1 --- Comment #2 from Paolo Carlini --- By the way, now clang does much better.
[Bug c++/50462] poor diagnostics for missing parenthesis in call to method
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50462 --- Comment #1 from Manuel López-Ibáñez 2011-09-20 13:59:47 UTC --- Clang does only marginally better because of its selective typedef unwrapping and avoiding printing back expressions, but then it goes and prints all candidates: /tmp/webcompile/_7569_0.cc:10:13: error: invalid operands to binary expression ('ostream' (aka 'basic_ostream') and '') { std::cout << v.size; } ~ ^ ~~ In file included from /tmp/webcompile/_7569_0.cc:1: In file included from /usr/include/c++/4.3/iostream:44: /usr/include/c++/4.3/ostream:111:7: note: candidate function not viable: no overload of 'size' matching '__ostream_type &(*)(__ostream_type &)' for 1st argument operator<<(__ostream_type& (*__pf)(__ostream_type&)) ^ /usr/include/c++/4.3/ostream:120:7: note: candidate function not viable: no overload of 'size' matching '__ios_type &(*)(__ios_type &)' for 1st argument operator<<(__ios_type& (*__pf)(__ios_type&)) ^ /usr/include/c++/4.3/ostream:130:7: note: candidate function not viable: no overload of 'size' matching 'std::ios_base &(*)(std::ios_base &)' for 1st argument operator<<(ios_base& (*__pf) (ios_base&)) ^ /usr/include/c++/4.3/ostream:168:7: note: candidate function not viable: no overload of 'size' matching 'long' for 1st argument operator<<(long __n) ^ /usr/include/c++/4.3/ostream:172:7: note: candidate function not viable: no overload of 'size' matching 'unsigned long' for 1st argument operator<<(unsigned long __n) ^ /usr/include/c++/4.3/ostream:176:7: note: candidate function not viable: no overload of 'size' matching 'bool' for 1st argument operator<<(bool __n) ^ /usr/include/c++/4.3/ostream:180:7: note: candidate function not viable: no overload of 'size' matching 'short' for 1st argument operator<<(short __n); ^ /usr/include/c++/4.3/ostream:183:7: note: candidate function not viable: no overload of 'size' matching 'unsigned short' for 1st argument operator<<(unsigned short __n) ^ /usr/include/c++/4.3/ostream:191:7: note: candidate function not viable: no overload of 'size' matching 'int' for 1st argument operator<<(int __n); ^ /usr/include/c++/4.3/ostream:194:7: note: candidate function not viable: no overload of 'size' matching 'unsigned int' for 1st argument operator<<(unsigned int __n) ^ /usr/include/c++/4.3/ostream:203:7: note: candidate function not viable: no overload of 'size' matching 'long long' for 1st argument operator<<(long long __n) ^ /usr/include/c++/4.3/ostream:207:7: note: candidate function not viable: no overload of 'size' matching 'unsigned long long' for 1st argument operator<<(unsigned long long __n) ^ /usr/include/c++/4.3/ostream:212:7: note: candidate function not viable: no overload of 'size' matching 'double' for 1st argument operator<<(double __f) ^ /usr/include/c++/4.3/ostream:216:7: note: candidate function not viable: no overload of 'size' matching 'float' for 1st argument operator<<(float __f) ^ /usr/include/c++/4.3/ostream:224:7: note: candidate function not viable: no overload of 'size' matching 'long double' for 1st argument operator<<(long double __f) ^ /usr/include/c++/4.3/ostream:228:7: note: candidate function not viable: no overload of 'size' matching 'const void *' for 1st argument operator<<(const void* __p) ^ /usr/include/c++/4.3/ostream:253:7: note: candidate function not viable: no overload of 'size' matching '__streambuf_type *' (aka 'basic_streambuf > *') for 1st argument operator<<(__streambuf_type* __sb); ^ /usr/include/c++/4.3/ostream:449:5: note: candidate function [with _CharT = char, _Traits = std::char_traits] not viable: no overload of 'size' matching 'char' for 2nd argument operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c) ^ /usr/include/c++/4.3/ostream:454:5: note: candidate function [with _CharT = char, _Traits = std::char_traits] not viable: no overload of 'size' matching 'char' for 2nd argument operator<<(basic_ostream<_CharT, _Traits>& __out, char __c) ^ /usr/include/c++/4.3/ostream:460:5: note: candidate function [with _Traits = std::char_traits] not viable: no overload of 'size' matching 'char' for 2nd argument operator<<(basic_ostream& __out, char __c) ^ /usr/include/c++/4.3/ostream:466:5: note: candidate function [with _Traits = std::char_traits] not viable: no overload of 'size' matching 'signed char' for 2nd argument operator<<(basic_ostream& __out, signed char __c) ^ /usr/include/c++/4.3/ostream:471:5: note: candidate function [with _Traits = std::char_traits] not viable: no overload of 'size' matching 'unsigned char' for 2nd argument operator<<(basic_ostream& __out, unsigned char __c) ^ /usr/include/c++/4.3/ostream:491:5: note: candidate function [with _CharT = char, _Traits = std::char_traits] not viable: no overload of 'size'