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

C++: Remove FPs from cpp/too-few-arguments #17919

Merged
merged 6 commits into from
Nov 22, 2024

Conversation

calumgrant
Copy link
Contributor

@calumgrant calumgrant commented Nov 6, 2024

Fixes https://github.com/github/codeql-c-team/issues/2462

False-positives in this query were due to implicit C function definitions. Arguably, we shouldn't report this alert for implicit C function definitions, because these are much more likely to be extraction errors rather than actual problems.

The current tests pretty well covered the existing behaviour, so I just reused this test.

Pull Request checklist

All query authors

Internal query authors only

  • Autofixes generated based on these changes are valid, only needed if this PR makes significant changes to .ql, .qll, or .qhelp files. See the documentation (internal access required).
  • Changes are validated at scale (internal access required).
  • Adding a new query? Consider also adding the query to autofix.

@github-actions github-actions bot added the C++ label Nov 6, 2024
@calumgrant calumgrant force-pushed the calumgrant/bmn/too-few-arguments branch from aa02a12 to 68cafc6 Compare November 8, 2024 15:56
Comment on lines +55 to +56
// Don't report on implicit function declarations, as these are likely extraction errors.
not f.getADeclarationEntry().isImplicit()
Copy link
Contributor

@jketema jketema Nov 15, 2024

Choose a reason for hiding this comment

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

I wonder if this is too strict, given the test results that disappear. Shouldn't this be something like:

  • if all declaration entries are implicit, then ignore
  • if the explicit declaration entries differ on the number of parameters, then ignore

Edit: fixed typos where I wrote "explicit", but meant "implicit", and vice versa.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

One of the scenarios I'd like to handle is something like

file1.c:

// Decl/definition
void assert(pchar __file, unsigned int __line, pchar __function);

file2.c:

assert(x);  // Implicit fn decl because the assert macro isn't defined

In this case, some fndecl entries are explicit, and all explicit fndecls have the same number of parameters.

So I can write

forex(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
    fde.getNumberOfParameters() = f.getNumberOfParameters()
  )

but this basically covers the case above. If we weaken it to

  forex(FunctionDeclarationEntry fde | fde = f.getAnExplicitDeclarationEntry() |
    fde.getNumberOfParameters() = f.getNumberOfParameters()
  ) and

then this doesn't handle the assert case above and doesn't get rid of all the noise.

Copy link
Contributor

@geoffw0 geoffw0 Nov 18, 2024

Choose a reason for hiding this comment

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

What if you move not f.getADeclarationEntry().isImplicit() into hasDefiniteNumberOfParameters?

Copy link
Contributor

Choose a reason for hiding this comment

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

If this is just to handle assert: I would expect there to be some macro definition of assert to be in scope. Unless the particular project you're looking at hand-rolled the definition, and we're not managing to pick up on the correct header file?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What if you move not f.getADeclarationEntry().isImplicit() into hasDefiniteNumberOfParameters?

That didn't remove the FPs. I think it's because implicit FunctionDeclarationEntry always have 0 parameters anyway.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If this is just to handle assert: I would expect there to be some macro definition of assert to be in scope. Unless the particular project you're looking at hand-rolled the definition, and we're not managing to pick up on the correct header file?

The FPs have also appeared on projects that don't involve macros or assert. In the case of assert, most likely the wrong header file was included or couldn't be found.

It would be possible to remove some FPs simply by saying and not exists(Macro m | m.getName() = f.getName()) but that's very specific and doesn't cover the cases where there isn't a macro involved.

In the general case, we'd hope to improve header file resolution, but we should expect this to go wrong at times.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's because implicit FunctionDeclarationEntry always have 0 parameters anyway.

Correct. An implicit function declarations foo always have the form extern int foo().

@calumgrant calumgrant marked this pull request as ready for review November 18, 2024 09:02
@calumgrant calumgrant requested a review from a team as a code owner November 18, 2024 09:02
@jketema
Copy link
Contributor

jketema commented Nov 18, 2024

Looking at a comparison between traced and BMN in DCA, I see that there are 0 results in the traced run and many (211) results in the BMN run. I wonder if the discussion here should actually be whether we should disable the query with BMN?

@calumgrant
Copy link
Contributor Author

Looking at a comparison between traced and BMN in DCA, I see that there are 0 results in the traced run and many (211) results in the BMN run. I wonder if the discussion here should actually be whether we should disable the query with BMN?

I assume those 211 results are even with this fix?

@jketema
Copy link
Contributor

jketema commented Nov 18, 2024

I assume those 211 results are even with this fix?

That's before this fix.

@jketema
Copy link
Contributor

jketema commented Nov 21, 2024

@calumgrant Could you re-run the traced DCA experiment? Two projects seemed to have failed.

Comment on lines -1 to -2
| test.c:34:3:34:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:32:3:32:3 | not_yet_declared2 | not_yet_declared2 |
| test.c:34:3:34:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:76:6:76:22 | not_yet_declared2 | not_yet_declared2 |
Copy link
Contributor

@jketema jketema Nov 22, 2024

Choose a reason for hiding this comment

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

The test.c file probably needs to be updated to indicated that we do not detect these.

Comment on lines 33 to 34
not_yet_declared2(ca); // BAD (GOOD for everything except for cpp/mistyped-function-arguments)
not_yet_declared2(); // GOOD
Copy link
Contributor

Choose a reason for hiding this comment

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

I think changing this to "GOOD" is incorrect. It's still "BAD", but we no longer detect it. For that we have "BAD [NOT DETECTED]". That probably does need some qualification here, as that only applies to cpp/too-few-arguments.

---
category: minorAnalysis
---
* The "Call to function with fewer arguments than declared parameters" query (`cpp/too-few-arguments`) query produces no results if the function has been implicitly declared.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* The "Call to function with fewer arguments than declared parameters" query (`cpp/too-few-arguments`) query produces no results if the function has been implicitly declared.
* The "Call to function with fewer arguments than declared parameters" query (`cpp/too-few-arguments`) query no longer produces results if the function has been implicitly declared.

jketema
jketema previously approved these changes Nov 22, 2024
Copy link
Contributor

@jketema jketema left a comment

Choose a reason for hiding this comment

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

LGTM. My conclusion is there there probably not better way to do this, and given the kinds of results we saw in MRVA there also seems no need to come up with anything smarter.

@calumgrant calumgrant merged commit b1b62f2 into main Nov 22, 2024
14 checks passed
@calumgrant calumgrant deleted the calumgrant/bmn/too-few-arguments branch November 22, 2024 16:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants