mirror of
https://github.com/github/codeql.git
synced 2026-05-03 12:45:27 +02:00
[CPP-340] Create QL query for function call argument count mismatches.
Update QHELP file, test and test results.
This commit is contained in:
@@ -5,18 +5,25 @@
|
||||
|
||||
|
||||
<overview>
|
||||
<p>A function is called with arguments despite having an empty parameter list. This may indicate
|
||||
that the incorrect function is being called, or that the author misunderstood the function.</p>
|
||||
<p>A function is called with arguments despite having been <i>declared</i> with an empty parameter list.
|
||||
In addition, we were either unable to find a <i>definition</i> of the function, or found one with
|
||||
an incompatible number of parameters.</p>
|
||||
|
||||
<p>This may indicate that an incorrect function is being called, or that the signature (parameter list)
|
||||
of the called function is not known to the author.</p>
|
||||
|
||||
<p>In C, a function declared with an empty parameter list <code>()</code> is considered to have an unknown
|
||||
parameter list, and therefore can be called with any set of arguments. To declare a function
|
||||
which takes no arguments, you must use <code>(void)</code> as the parameter list in any forward declarations.
|
||||
In C++, either style of declaration indicates that the function accepts no arguments.</p>
|
||||
In C++, <code>()</code> means the same as <code>(void)</code>, i.e., indicates that the function accepts no
|
||||
arguments.</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
<p>Call the function without arguments, or call a different function that expects the arguments
|
||||
being passed.</p>
|
||||
being passed. If possible, change the forward declaration of the <code>()</code>-function to reflect the
|
||||
arguments being passed, or change the <code>()</code> to <code>(void)</code> to indicate that no arguments
|
||||
shall be passed.</p>
|
||||
|
||||
</recommendation>
|
||||
<example><sample src="FutileParams.c" />
|
||||
|
||||
@@ -12,11 +12,14 @@
|
||||
|
||||
import cpp
|
||||
|
||||
from Function f, FunctionCall fc
|
||||
where fc.getTarget() = f
|
||||
and f.getNumberOfParameters() = 0
|
||||
and not f.isVarargs()
|
||||
and fc.getNumberOfArguments() != 0
|
||||
and not f instanceof BuiltInFunction
|
||||
and exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() | not fde.isImplicit())
|
||||
select fc, "This call has arguments, but $@ is not declared with any parameters.", f, f.toString()
|
||||
from FunctionCall fc, Function f
|
||||
where f = fc.getTarget() and not f.isVarargs()
|
||||
/* There must be a mismatch between number of call arguments and number of parameters in some
|
||||
* non-implicit declaration of Function f
|
||||
*/
|
||||
and exists ( FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() | not fde.isImplicit() and fde.getNumberOfParameters() != fc.getNumberOfArguments())
|
||||
/* There must be no _definition_ of Function f whose number of parameters matches number of call arguments */
|
||||
and not exists ( FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() | fde.isDefinition() and fde.getNumberOfParameters() = fc.getNumberOfArguments())
|
||||
select fc
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
| test.c:8:3:8:16 | call to declared_empty | This call has arguments, but $@ is not declared with any parameters. | test.c:1:6:1:19 | declared_empty | declared_empty |
|
||||
| test.c:14:3:14:19 | call to not_yet_declared1 | This call has arguments, but $@ is not declared with any parameters. | test.c:14:3:14:3 | not_yet_declared1 | not_yet_declared1 |
|
||||
| test.c:14:3:14:19 | call to not_yet_declared1 | This call has arguments, but $@ is not declared with any parameters. | test.c:25:6:25:22 | not_yet_declared1 | not_yet_declared1 |
|
||||
| test.c:7:3:7:16 | call to declared_empty |
|
||||
| test.c:16:3:16:19 | call to not_yet_declared1 |
|
||||
| test.c:19:3:19:29 | call to declared_empty_defined_with |
|
||||
| test.c:24:3:24:29 | call to declared_empty_defined_with |
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
void declared_empty();
|
||||
void declared_void(void);
|
||||
void declared_with(int);
|
||||
void declared_empty_defined_with();
|
||||
|
||||
void test() {
|
||||
declared_empty(); // GOOD
|
||||
@@ -9,17 +8,20 @@ void test() {
|
||||
declared_void(); // GOOD
|
||||
declared_with(1); // GOOD
|
||||
|
||||
declared_ellipsis(); // GOOD
|
||||
declared_ellipsis(2); // GOOD
|
||||
|
||||
undeclared(1); // GOOD
|
||||
|
||||
not_yet_declared1(1); // BAD
|
||||
not_yet_declared2(1); // GOOD
|
||||
|
||||
declared_empty_defined_with(); // BAD [NOT DETECTED]
|
||||
declared_empty_defined_with(); // BAD
|
||||
declared_empty_defined_with(1); // GOOD
|
||||
|
||||
int x;
|
||||
declared_empty_defined_with(&x); // BAD [NOT DETECTED]
|
||||
declared_empty_defined_with(x, x); // BAD [NOT DETECTED]
|
||||
declared_empty_defined_with(&x); // GOOD
|
||||
declared_empty_defined_with(x, x); // BAD
|
||||
}
|
||||
|
||||
void not_yet_declared1();
|
||||
|
||||
Reference in New Issue
Block a user