[Bug c++/77711] Add fix-it hints for missing parentheses in member function call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77711 Jonathan Wakely changed: What|Removed |Added Assignee|redi at gcc dot gnu.org|unassigned at gcc dot gnu.org Target Milestone|11.0|--- Status|ASSIGNED|NEW
[Bug c++/77711] Add fix-it hints for missing parentheses in member function call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77711 Jonathan Wakely changed: What|Removed |Added Target Milestone|10.2|11.0
[Bug c++/77711] Add fix-it hints for missing parentheses in member function call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77711 Jakub Jelinek changed: What|Removed |Added Target Milestone|10.0|10.2 --- Comment #11 from Jakub Jelinek --- GCC 10.1 has been released.
[Bug c++/77711] Add fix-it hints for missing parentheses in member function call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77711 Jonathan Wakely changed: What|Removed |Added Target Milestone|9.3 |10.0
[Bug c++/77711] Add fix-it hints for missing parentheses in member function call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77711 Jakub Jelinek changed: What|Removed |Added Target Milestone|9.2 |9.3 --- Comment #10 from Jakub Jelinek --- GCC 9.2 has been released.
[Bug c++/77711] Add fix-it hints for missing parentheses in member function call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77711 Jakub Jelinek changed: What|Removed |Added Target Milestone|9.0 |9.2 --- Comment #9 from Jakub Jelinek --- GCC 9.1 has been released.
[Bug c++/77711] Add fix-it hints for missing parentheses in member function call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77711 --- Comment #8 from Jonathan Wakely --- My patch doesn't help for comment 2 because we never call invalid_nonstatic_member_fn when the nonsense expression refers to the name of an overloaded member function. Instead we perform overload resolution hoping that one of the overloads will disambiguate a.foo, which will never happen. See Bug 50462 for a case very similar to comment 2 where we end up with over 200 lines of noise simply because don't stop as soon as we see an invalid member function call, and try to perform overload resolution on it instead.
[Bug c++/77711] Add fix-it hints for missing parentheses in member function call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77711 Jonathan Wakely changed: What|Removed |Added Status|NEW |ASSIGNED Assignee|dmalcolm at gcc dot gnu.org|redi at gcc dot gnu.org --- Comment #7 from Jonathan Wakely --- Mine.
[Bug c++/77711] Add fix-it hints for missing parentheses in member function call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77711 David Malcolm changed: What|Removed |Added CC||dmalcolm at gcc dot gnu.org Assignee|unassigned at gcc dot gnu.org |dmalcolm at gcc dot gnu.org Target Milestone|--- |9.0
[Bug c++/77711] Add fix-it hints for missing parentheses in member function call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77711 --- Comment #6 from Jonathan Wakely --- Yet another variation on missing argument list for a member function call: call.cc: In function ‘int main()’: call.cc:20:14: error: cannot convert ‘A::foo’ from type ‘int (A::)()’ to type ‘int (A::*)()’ auto x = a.foo; ^~~ Another completely different error, that's also pretty unhelpful. This should probably use invalid_nonstatic_memfn_p too. Clang gives exactly the same error in this case as for the bar( a.foo ) case, which is much better than two different unclear messages.
[Bug c++/77711] Add fix-it hints for missing parentheses in member function call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77711 --- Comment #5 from Jonathan Wakely --- For comparison, clang gives a much clearer error: 77711.cc:11:9: error: reference to non-static member function must be called; did you mean to call it with no arguments? x.f ~~^ () It says *why* it's invalid (it must be called), and suggests adding an empty argument list (including when the function has parameters but they have default arguments). I have a fix for PR7 so we can print the same range info and fix-it as clang does.
[Bug c++/77711] Add fix-it hints for missing parentheses in member function call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77711 --- Comment #4 from Jonathan Wakely --- Ideally we'd look to see if a.foo() would return a type that would make the call bar( a.foo() ) valid, and not suggest it otherwise (there's no point suggesting it if a.foo() returns void, for example). And we could also look to see if bar( ::foo ) would be valid, and suggest that if so. Sometimes either would be valid, e.g. template void bar(T).
[Bug c++/77711] Add fix-it hints for missing parentheses in member function call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77711 --- Comment #3 from Jonathan Wakely --- With: --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1823,6 +1823,7 @@ invalid_nonstatic_memfn_p (location_t loc, tree expr, tsubst_flags_t complain) /* Don't enforce this in MS mode. */ if (flag_ms_extensions) return false; + tree origexpr = expr; if (is_overloaded_fn (expr) && !really_overloaded_fn (expr)) expr = get_first_fn (expr); if (DECL_NONSTATIC_MEMBER_FUNCTION_P (expr)) @@ -1831,8 +1832,18 @@ invalid_nonstatic_memfn_p (location_t loc, tree expr, tsubst_flags_t complain) { if (DECL_P (expr)) { - error_at (loc, "invalid use of non-static member function %qD", - expr); + tree args = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (expr))); + if (list_length (args) == 1) + { +gcc_rich_location richloc (loc); +richloc.add_fixit_insert_before(loc, "()"); +error_at_rich_loc (, "invalid use of non-static " + "member function %qD; did you mean " + "%<%E()%>?", expr, origexpr); + } + else +error_at (loc, "invalid use of non-static member function %qD", + expr); inform (DECL_SOURCE_LOCATION (expr), "declared here"); } else the first example gives: call.cc: In function ‘int main()’: call.cc:19:14: error: invalid use of non-static member function ‘int A::foo()’; did you mean ‘a.A::foo()’? bar( a.foo ); ^ () call.cc:2:7: note: declared here int foo(); ^~~ Which is OK, but not great. It should say a.foo() not a.A::foo(). The fixit is correct, but it would be better if we had a rich_location covering a.foo rather than a non-rich one pointing to the next token (PR7). In this specific example inserting () at the suggested location would match the GNU coding standards (with a space before the parentheses) but nobody writes C++ like that, and it's not correct if there's any more whitespace before the next token.
[Bug c++/77711] Add fix-it hints for missing parentheses in member function call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77711 --- Comment #2 from Jonathan Wakely --- And then if the function we're calling is a member function we get another variation: struct A { int foo(); int foo() const; void bar(int); }; int main() { A a; a.bar( a.foo ); } foo.cc: In function ‘int main()’: foo.cc:11:16: error: no matching function for call to ‘A::bar()’ a.bar( a.foo ); ^ foo.cc:4:8: note: candidate: void A::bar(int) void bar(int); ^~~ foo.cc:4:8: note: no known conversion for argument 1 from ‘’ to ‘int’ Again, we shouldn't even be trying to find a matching A::bar, because a.foo is nonsense. In all three examples we should notice that a.foo is invalid and give an error, suggesting either a.foo() (to call it) or ::foo (to form a pointer to the member function).
[Bug c++/77711] Add fix-it hints for missing parentheses in member function call
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77711 Jonathan Wakely changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2016-09-23 Ever confirmed|0 |1 --- Comment #1 from Jonathan Wakely --- If the function is overloaded we get a different, equally unhelpful error: struct A { int foo(); int foo() const; }; void bar(int); int main() { A a; bar( a.foo ); } foo.cc: In function ‘int main()’: foo.cc:11:14: error: cannot resolve overloaded function ‘foo’ based on conversion to type ‘int’ bar( a.foo ); ^ 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. This should also suggest a.foo()