C++: Only give alert when no def fits arg count

The `cpp/too-few-arguments` query produced alerts for ambiguous
databases where a function had multiple possible declarations, with some
declarations having the right number of parameters and some having too
many. With this change, the query errs on the side of caution in those
cases and does not produce an alert.

This fixes false positives on racket/racket.

The new `hasDefiniteNumberOfParameters` is exactly the negation of the
old `hasZeroParamDecl`.
This commit is contained in:
Jonas Jensen 2020-05-25 14:38:46 +02:00
Родитель 0d75c6a5f1
Коммит b1edc1d255
1 изменённых файлов: 24 добавлений и 4 удалений

Просмотреть файл

@ -6,10 +6,23 @@
import cpp import cpp
/**
* Holds if `fde` has a parameter declaration that's clear on the minimum
* number of parameters. This is essentially true for everything except
* `()`-declarations.
*/
private predicate hasDefiniteNumberOfParameters(FunctionDeclarationEntry fde) {
fde.hasVoidParamList()
or
fde.getNumberOfParameters() > 0
or
fde.isDefinition()
}
// True if function was ()-declared, but not (void)-declared or K&R-defined // True if function was ()-declared, but not (void)-declared or K&R-defined
private predicate hasZeroParamDecl(Function f) { private predicate hasZeroParamDecl(Function f) {
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() | exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
not fde.hasVoidParamList() and fde.getNumberOfParameters() = 0 and not fde.isDefinition() not hasDefiniteNumberOfParameters(fde)
) )
} }
@ -24,11 +37,18 @@ predicate tooFewArguments(FunctionCall fc, Function f) {
f = fc.getTarget() and f = fc.getTarget() and
not f.isVarargs() and not f.isVarargs() and
not f instanceof BuiltInFunction and not f instanceof BuiltInFunction and
// This query should only have results on C (not C++) functions that have a
// `()` parameter list somewhere. If it has results on other functions, then
// it's probably because the extractor only saw a partial compilation.
hasZeroParamDecl(f) and hasZeroParamDecl(f) and
isCompiledAsC(f.getFile()) and isCompiledAsC(f.getFile()) and
// There is an explicit declaration of the function whose parameter count is larger // Produce an alert when all declarations that are authoritative on the
// than the number of call arguments // parameter count specify a parameter count larger than the number of call
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() | // arguments.
forex(FunctionDeclarationEntry fde |
fde = f.getADeclarationEntry() and
hasDefiniteNumberOfParameters(fde)
|
fde.getNumberOfParameters() > fc.getNumberOfArguments() fde.getNumberOfParameters() > fc.getNumberOfArguments()
) )
} }