Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display argument errors for non-overloaded functions in C++. #2621

Closed
6 of 12 tasks
lvella opened this issue Apr 17, 2017 · 7 comments
Closed
6 of 12 tasks

Display argument errors for non-overloaded functions in C++. #2621

lvella opened this issue Apr 17, 2017 · 7 comments

Comments

@lvella
Copy link

lvella commented Apr 17, 2017

Issue Prelude

Please complete these steps and check these boxes (by putting an x inside
the brackets) before filing your issue:

  • I have read and understood YCM's [CONTRIBUTING][cont] document.
  • I have read and understood YCM's [CODE_OF_CONDUCT][code] document.
  • I have read and understood YCM's [README][readme], especially the
    [Frequently Asked Questions][faq] section.
  • I have searched YCM's issue tracker to find issues similar to the one I'm
    about to report and couldn't find an answer to my problem. ([Example Google
    search.][search])
  • If filing a bug report, I have included the output of vim --version.
  • If filing a bug report, I have included the output of :YcmDebugInfo.
  • If filing a bug report, I have attached the contents of the logfiles using
    the :YcmToggleLogs command.
  • If filing a bug report, I have included which OS (including specific OS
    version) I am using.
  • If filing a bug report, I have included a minimal test case that reproduces
    my issue, including what I expected to happen and what actually happened.
  • If filing a installation failure report, I have included the entire output
    of install.py (or cmake/make/ninja) including its invocation
  • I understand this is an open-source project staffed by volunteers and
    that any help I receive is a selfless, heartfelt gift of their free time. I
    know I am not entitled to anything and will be polite and courteous.
  • I understand my issue may be closed if it becomes obvious I didn't
    actually perform all of these steps.

Issue Details

This is not a bug report, but a feature request specific for C++.

Absolute majority of my functions are not overloaded (and I believe this is the case for most C++ projects). Some even are declared inside extern "C" {}, which means they can't be overloaded. The problem is when calling a function with wrong parameters, YCM displays the error no matching function for call to 'func_name', and highlights the function name, instead of displaying what is wrong with the arguments and highlighting the arguments.

My suggestion is: when there is only one possible candidate (or even maybe only one candidate with that number of parameters), YCM should display the reason why that particular function candidate failed, highlighting the offending arguments. Most of the times it would be far more useful than the no matching function for call ... error.

@puremourning
Copy link
Member

Could you please include a reproducible minimal test case including what you did, what you expected to happen (assuming your feature request is implemented) and what actually happens.

FWIW our diagnostics reporting come from libclang, so there is likely no way for YCM to provide the feature, but it isn't completely clear what scenario you're describing.

Thanks.

@lvella
Copy link
Author

lvella commented Apr 17, 2017

When displaying errors for the following code:

#include <memory>

struct A {};

void f(A* ptr)
{}

int main()
{
	std::unique_ptr<A> a(new A);

	// Error:
	f(a);

	// Should be:
	f(a.get());
}

It displays on the erroneous line:
no matching function for call to 'f'

But when I compile with clang++, the error is more detailed:

$ clang++-3.9 test.cpp -std=c++11 -c
test.cpp:13:2: error: no matching function for call to 'f'
        f(a);
        ^
test.cpp:5:6: note: candidate function not viable: no known conversion from 'std::unique_ptr<A>' to 'A *' for 1st argument
void f(A* ptr)
     ^
1 error generated.

So, in these cases, where the function is not overloaded, or there is only one overloaded function with the same number of arguments, the error shown inside Vim should be something like the note message from the compiler: no known conversion from 'std::unique_ptr<A>' to 'A *' for 1st argument.

@puremourning
Copy link
Member

If you put the cursor on the line with the error and type :YcmShowDetailedDiagnostic do you get the errors you expect?

https://github.com/Valloric/YouCompleteMe#the-ycmshowdetaileddiagnostic-command

@lvella
Copy link
Author

lvella commented Apr 17, 2017

Yes. But that is not the point. I argue that, in this specific common cases, the note is a more useful short message than the error.

@puremourning
Copy link
Member

Thanks, i understand. To be honest, I'm not sure if there is a programmatic way for us to know that, however.

@bstaletic
Copy link
Collaborator

I've given some thought to this, but unfortunately think there is nothing we can do to help this particular case.

Libclang's API and thus clang completer can indeed differentiate between errors, warnings and notes. So my inital idea would be to check if line has and notes and if so the short message should be the note. Since notes don't ever come alone and people don't prioritise them over errors or warnings the sign shouldn't be the colour of a note. Instead let's check if the note is attateched to a warning or an error and display the appropriate sign.

This however is a terrible idea in case of templates. A simple error with template objects, methods and others usually produces a comprehensible error message in the first few lines and then a ton of notes about every possible choice for the typename. Prioritising notes here would be a big mistake. I'll demonstrate this with a pretty mild case.

Let's compile the following C++ file:

#include <functional>
#include <vector>

int main(void) {
    std::hash< std::vetor< std::string > > a;
    return 0;
}

G++ errors:

a.cpp: In function ‘int main()’:
a.cpp:6:42: error: use of deleted function ‘std::hash<std::vector<std::__cxx11::basic_string<char> > >::hash()’
  std::hash< std::vector< std::string > > a;
                                          ^
In file included from /usr/include/c++/6.3.1/bits/basic_string.h:5643:0,
                 from /usr/include/c++/6.3.1/string:52,
                 from /usr/include/c++/6.3.1/stdexcept:39,
                 from /usr/include/c++/6.3.1/array:39,
                 from /usr/include/c++/6.3.1/tuple:39,
                 from /usr/include/c++/6.3.1/functional:55,
                 from a.cpp:1:
/usr/include/c++/6.3.1/bits/functional_hash.h:85:12: note: ‘std::hash<std::vector<std::__cxx11::basic_string<char> > >::hash()’ is implicitly deleted because the default definition would be ill-formed:
     struct hash : __hash_enum<_Tp>
            ^~~~
/usr/include/c++/6.3.1/bits/functional_hash.h:85:12: error: no matching function for call to ‘std::__hash_enum<std::vector<std::__cxx11::basic_string<char> >, false>::__hash_enum()’
/usr/include/c++/6.3.1/bits/functional_hash.h:66:7: note: candidate: std::__hash_enum<_Tp, <anonymous> >::__hash_enum(std::__hash_enum<_Tp, <anonymous> >&&) [with _Tp = std::vector<std::__cxx11::basic_string<char> >; bool <anonymous> = false]
       __hash_enum(__hash_enum&&);
       ^~~~~~~~~~~
/usr/include/c++/6.3.1/bits/functional_hash.h:66:7: note:   candidate expects 1 argument, 0 provided
/usr/include/c++/6.3.1/bits/functional_hash.h:85:12: error: ‘std::__hash_enum<_Tp, <anonymous> >::~__hash_enum() [with _Tp = std::vector<std::__cxx11::basic_string<char> >; bool <anonymous> = false]’ is private within this context
     struct hash : __hash_enum<_Tp>
            ^~~~
/usr/include/c++/6.3.1/bits/functional_hash.h:67:7: note: declared private here
       ~__hash_enum();
       ^
a.cpp:6:42: error: use of deleted function ‘std::hash<std::vector<std::__cxx11::basic_string<char> > >::~hash()’
  std::hash< std::vector< std::string > > a;
                                          ^
In file included from /usr/include/c++/6.3.1/bits/basic_string.h:5643:0,
                 from /usr/include/c++/6.3.1/string:52,
                 from /usr/include/c++/6.3.1/stdexcept:39,
                 from /usr/include/c++/6.3.1/array:39,
                 from /usr/include/c++/6.3.1/tuple:39,
                 from /usr/include/c++/6.3.1/functional:55,
                 from a.cpp:1:
/usr/include/c++/6.3.1/bits/functional_hash.h:85:12: note: ‘std::hash<std::vector<std::__cxx11::basic_string<char> > >::~hash()’ is implicitly deleted because the default definition would be ill-formed:
     struct hash : __hash_enum<_Tp>
            ^~~~
/usr/include/c++/6.3.1/bits/functional_hash.h:85:12: error: ‘std::__hash_enum<_Tp, <anonymous> >::~__hash_enum() [with _Tp = std::vector<std::__cxx11::basic_string<char> >; bool <anonymous> = false]’ is private within this context
/usr/include/c++/6.3.1/bits/functional_hash.h:67:7: note: declared private here
       ~__hash_enum();
       ^

Clang however is much smarter in this case:

/6.3.1/bits/functional_hash.h:67:7: note: declared private here
       ~__hash_enum();
       ^

Clang++ errors:

a.cpp:6:42: error: call to implicitly-deleted default constructor of 'std::hash<std::vector<std::string> >' (aka 'hash<vector<basic_string<char> > >')
        std::hash< std::vector< std::string > > a;
                                                ^
/usr/sbin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../include/c++/6.3.1/bits/functional_hash.h:85:19: note: default constructor of 'hash<std::vector<std::__cxx11::basic_string<char>, std::allocator<std::__cxx11::basic_string<char> > > >' is implicitly deleted because base class '__hash_enum<std::vector<std::__cxx11::basic_string<char>, std::allocator<std::__cxx11::basic_string<char> > > >' has no default constructor
    struct hash : __hash_enum<_Tp>
                  ^
1 error generated.

Templates can produce a flood of weird combinatioin of errors or warnings and messages.

For a bad case of non-templated code errors take a look at this stackoverflow post.

@bstaletic
Copy link
Collaborator

Like I mentioned in the previous comment, it would be impossible to selectively give priority to note:s and do it right, so I'm going to close this.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 12, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants