Open llvmbot opened 14 years ago
mentioned in issue llvm/llvm-bugzilla-archive#8056
As of r158660, clang produces much better results for both of the examples mentioned in this bug.
For the example in the original description: $ cat tmp.cc struct A; A f0(int x, float y); void f1(A ); void f2() { f1(f0); }
$ ./bin/clang -fsyntax-only tmp.cc tmp.cc:4:13: error: no matching function for call to 'f1' void f2() { f1(f0); } ^~ tmp.cc:3:6: note: candidate function not viable: no known conversion from 'A (int, float)' to 'A ' for 1st argument; void f1(A *); ^ 1 error generated.
And for Jeffry Yasskin's example:
$ cat tmp.cc struct string { bool operator==(const char*); }; struct A { string foo(); }; bool bar() { A a; return a.foo == "Hello World"; }
$ ./bin/clang -fsyntax-only tmp.cc
tmp.cc:9:12: error: reference to non-static member function must be called; did you mean to call it
with no arguments?
return a.foo == "Hello World";
^
()
1 error generated.
It looks like all that is left to do is provide a suggestion to add the missing parens in the overload resolution, as is done with the second (non-overloaded) example when adding parens would actually help. In the original example it wouldn't because f0 takes two arguments... though changing it to take zero arguments results in the same "no known conversion..." message without a suggestion for adding parens.
Bug llvm/llvm-bugzilla-archive#8056 has been marked as a duplicate of this bug.
Here's a similar case of forgotten parens that doesn't involve overload resolution:
$ cat test.cc struct string { bool operator==(const char*); };
struct A { string foo(); };
bool bar() { A a; return a.foo == "Hello World"; }
$ Debug/bin/clang -fsyntax-only test.cc
test.cc:11:16: warning: result of comparison against a string literal
is unspecified (use strncmp instead)
return a.foo == "Hello World";
^ ~~~~~
test.cc:11:16: error: comparison of distinct pointer types
('string ()()' and 'char const ')
return a.foo == "Hello World";
1 warning and 1 error generated.
We do slightly better in C:
t.c:4:16: warning: incompatible pointer types passing 'struct A (int, float)', expected 'struct A ' void f2() { f1(f0); }
The idea here is to add a fix-it suggesting the addition of ()'s after the use of f0, since calling the function would have made the program well-formed. We could tackle the C case here, then improve the C++ case when we address llvm/llvm-project#3476 .
We are doing a lot better, but it would be nice if clang could suggest adding parens in this case:
struct A;
A *f0();
void f1(A *);
void f2() { f1(f0); }
(Godbolt)
Extended Description
Somehow I manage to do this all the time, and the resulting C++ warnings are frequently totally awesome.
ddunbar@giles:tmp$ cat t.cpp
ddunbar@giles:tmp$ gcc t.cpp
ddunbar@giles:tmp$ clang -fsyntax-only t.cpp
ddunbar@giles:tmp$