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

Fix detecting type responsible for operator function for function templates #399

Closed

Conversation

vsapsai
Copy link
Contributor

@vsapsai vsapsai commented Jan 22, 2017

Relevant discussion can be found in issue #384: Build fails after Clang r289250.

Check function parameters types instead of types of arguments at call
site. This way we are able to detect template substitutions for the
function itself, not for the caller.
operator== calls I1_const_ptr<T>::operator* and after Clang r289250 we
correctly detect that the return type of

  const T& operator*() { return *ptr_; }

is LValueReferenceType and doesn't require full type use.
Copy link
Contributor

@kimgr kimgr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, came to think of some small things

// Handle free functions.
int params_count = callee_decl->getNumParams();
for (int i = 0; i < params_count; i++) {
// View argument types from the perspective of function body, not from
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/body/declaration/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

for (int i = 0; i < params_count; i++) {
// View argument types from the perspective of function body, not from
// the caller's perspective. For example, function parameter can have
// template type but function argument is not necesserily a template
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: necesserily

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Thanks for catching this.

// In this case ('myclass >> os'), we want to be returning the
// type of os, not of myclass, and we do, because myclass will be
// a SubstTemplateTypeParmType, not a RecordType.
if (isa<SubstTemplateTypeParmType>(param_type))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this path ever hit now? It's a bit surprising that a parameter (as opposed to an argument) would be a SubstTemplateTypeParmType. I would have expected STTPT to only show up in the AST when instantiating a template/invoking a function template, but it's hard to tell from the docs what the respective nodes mean.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still required. Tried to remove it and GetFirstClassArgument wasn't doing its job.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, let's leave it at that :-)

return expr->getArg(0);
}
// Handle free functions.
int params_count = callee_decl->getNumParams();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we put in a CHECK_ here that params_count == expr's arg count?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... and actually, is that a strong invariant? I would expect things like:

void f(int a, int b=0);

f(10);

to break that.

Can't think of a case with operators and default arguments, so not sure if it's relevant.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added CHECK_. And regarding default arguments, I've tried it and hit a compiler error

tests/cxx/repo.cpp:28:39: error: parameter of overloaded 'operator==' cannot have a default argument
bool operator==(Cc_Class& object, int x = 0) {
                                      ^   ~

@vsapsai
Copy link
Contributor Author

vsapsai commented Jan 28, 2017

Addressed the comments, please check again.

@kimgr
Copy link
Contributor

kimgr commented Jan 28, 2017

Looks good to me, please merge.

vsapsai added a commit to vsapsai/include-what-you-use that referenced this pull request Jan 29, 2017
Check function parameters types instead of types of arguments at call
site. This way we are able to detect template substitutions for the
function itself, not for the caller.

PR include-what-you-use#399
vsapsai added a commit to vsapsai/include-what-you-use that referenced this pull request Jan 29, 2017
operator== calls I1_const_ptr<T>::operator* and after Clang r289250 we
correctly detect that the return type of

  const T& operator*() { return *ptr_; }

is LValueReferenceType and doesn't require full type use.

PR include-what-you-use#399
@vsapsai
Copy link
Contributor Author

vsapsai commented Jan 29, 2017

Merged manually 4e957bf and 1007562.

@vsapsai vsapsai closed this Jan 29, 2017
@kimgr kimgr modified the milestone: iwyu 0.8 Feb 19, 2017
huizongsong pushed a commit to huizongsong/include-what-you-use that referenced this pull request Aug 26, 2022
Check function parameters types instead of types of arguments at call
site. This way we are able to detect template substitutions for the
function itself, not for the caller.

PR include-what-you-use/include-what-you-use#399
huizongsong pushed a commit to huizongsong/include-what-you-use that referenced this pull request Aug 26, 2022
operator== calls I1_const_ptr<T>::operator* and after Clang r289250 we
correctly detect that the return type of

  const T& operator*() { return *ptr_; }

is LValueReferenceType and doesn't require full type use.

PR include-what-you-use/include-what-you-use#399
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants