mirror of
https://github.com/github/codeql.git
synced 2026-04-27 09:45:15 +02:00
[CPP-340] Add a fourth query, ArgumentsToImplicit.ql, to deal strictly with implicitly declared
functions. TooManyArguments.ql will now deal with explicitly declared/prototyped functions.
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
|
||||
void calls() {
|
||||
|
||||
undeclared(); // GOOD
|
||||
|
||||
undeclared(1); // BAD
|
||||
|
||||
undeclared(1, 2); // BAD
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
|
||||
<overview>
|
||||
<p>An implicitly-declared function is called with arguments.</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, an implicitly declared function is assumed to accept no arguments. Providing
|
||||
these arguments incurs an unneeded computational overhead, both
|
||||
in terms of time and of additional stack space.</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
<p>Call the function without any arguments.</p>
|
||||
|
||||
</recommendation>
|
||||
<example><sample src="ArgumentsToImplicit.c" />
|
||||
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>SEI CERT C Coding Standard: <a href="https://wiki.sei.cmu.edu/confluence/display/c/DCL20-C.+Explicitly+specify+void+when+a+function+accepts+no+arguments"> DCL20-C. Explicitly specify void when a function accepts no arguments </a></li>
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* @name Call with arguments to an implicitly declared function
|
||||
* @description A function call passed arguments even though the
|
||||
* function in question is only implicitly declared (and
|
||||
* hence accepting no arguments). This may indicate
|
||||
* that the code does not follow the author's intent.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @precision very-high
|
||||
* @id cpp/arguments-to-implicit
|
||||
* @tags correctness
|
||||
* maintainability
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
// True if there is no explicit definition of the function
|
||||
predicate hasNoExplicitDecl(Function f) {
|
||||
not exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
|
||||
not fde.isImplicit()
|
||||
)
|
||||
}
|
||||
|
||||
// True if this file (or header) was compiled as a C file
|
||||
predicate isCompiledAsC(Function f) {
|
||||
exists(File file | file.compiledAsC() |
|
||||
file = f.getFile() or file.getAnIncludedFile+() = f.getFile()
|
||||
)
|
||||
}
|
||||
|
||||
predicate isWhitelisted(Function f) {
|
||||
f instanceof BuiltInFunction
|
||||
or
|
||||
// The following list can be expanded as the need arises
|
||||
exists(string name | name = f.getName() |
|
||||
name = "static_assert" or
|
||||
name = "_Static_assert" or
|
||||
name = "strptime"
|
||||
)
|
||||
}
|
||||
|
||||
from FunctionCall fc, Function f
|
||||
where
|
||||
f = fc.getTarget() and
|
||||
hasNoExplicitDecl(f) and
|
||||
isCompiledAsC(f) and
|
||||
not isWhitelisted(f) and
|
||||
fc.getNumberOfArguments() > 0
|
||||
select fc, "This call to an implicitly declared function $@ has arguments.", f, f.toString()
|
||||
@@ -14,9 +14,13 @@
|
||||
import cpp
|
||||
|
||||
// True if function was ()-declared, but not (void)-declared or K&R-defined
|
||||
// or implicitly declared (i.e., lacking a prototype)
|
||||
predicate hasZeroParamDecl(Function f) {
|
||||
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
|
||||
not fde.hasVoidParamList() and fde.getNumberOfParameters() = 0 and not fde.isDefinition()
|
||||
not fde.isImplicit() and
|
||||
not fde.hasVoidParamList() and
|
||||
fde.getNumberOfParameters() = 0 and
|
||||
not fde.isDefinition()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user