From 0c350dc50476f22200c98a8c3815acaac7403b50 Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Mon, 18 Mar 2019 16:10:35 -0700
Subject: [PATCH 01/27] [CPP-340] Create QL query for function call argument
count mismatches. Update QHELP file, test and test results.
---
.../Likely Typos/FutileParams.qhelp | 15 +++++++++++----
.../Likely Bugs/Likely Typos/FutileParams.ql | 19 +++++++++++--------
.../FutileParams/FutileParams.expected | 7 ++++---
.../Likely Typos/FutileParams/test.c | 10 ++++++----
4 files changed, 32 insertions(+), 19 deletions(-)
diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.qhelp b/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.qhelp
index d0d888a9aac7..0c1e345c04fa 100644
--- a/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.qhelp
+++ b/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.qhelp
@@ -5,18 +5,25 @@
-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.
+A function is called with arguments despite having been declared with an empty parameter list.
+In addition, we were either unable to find a definition of the function, or found one with
+an incompatible number of parameters.
+
+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.
In C, a function declared with an empty parameter list () 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 (void) as the parameter list in any forward declarations.
-In C++, either style of declaration indicates that the function accepts no arguments.
+In C++, () means the same as (void), i.e., indicates that the function accepts no
+arguments.
Call the function without arguments, or call a different function that expects the arguments
-being passed.
+being passed. If possible, change the forward declaration of the ()-function to reflect the
+arguments being passed, or change the () to (void) to indicate that no arguments
+shall be passed.
diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.ql b/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.ql
index bb5a99a69bc9..c3f956f6deda 100644
--- a/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.ql
+++ b/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.ql
@@ -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
+
+
\ No newline at end of file
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/FutileParams.expected b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/FutileParams.expected
index d6dc2222be42..4bb782dfd11d 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/FutileParams.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/FutileParams.expected
@@ -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 |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/test.c b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/test.c
index 9589d2a9ffc9..ef81c416343a 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/test.c
+++ b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/test.c
@@ -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();
From 5d8b84c22a44240b2381c8cc72ee7481699910f2 Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Mon, 18 Mar 2019 17:23:03 -0700
Subject: [PATCH 02/27] Refine QL query by requiring that a ()-declaration be
present.
---
cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.ql | 2 ++
1 file changed, 2 insertions(+)
diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.ql b/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.ql
index c3f956f6deda..83baeaf8a95f 100644
--- a/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.ql
+++ b/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.ql
@@ -14,6 +14,8 @@ import cpp
from FunctionCall fc, Function f
where f = fc.getTarget() and not f.isVarargs()
+ /* There must be a zero-parameter declaration */
+ and exists ( FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() | fde.getNumberOfParameters() = 0)
/* There must be a mismatch between number of call arguments and number of parameters in some
* non-implicit declaration of Function f
*/
From 2def0ee9c1ce274d218e5796d8ea059657ed93a5 Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Tue, 19 Mar 2019 14:30:05 -0700
Subject: [PATCH 03/27] [CPP-340] Re-work QL query; treat undeclared C
functions the same way as ()-declared functions.
---
cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.ql | 10 +++++-----
.../Likely Typos/FutileParams/FutileParams.expected | 10 ++++++----
.../Likely Bugs/Likely Typos/FutileParams/test.c | 6 ++----
3 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.ql b/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.ql
index 83baeaf8a95f..c21afaf4ac9a 100644
--- a/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.ql
+++ b/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.ql
@@ -17,11 +17,11 @@ from FunctionCall fc, Function f
/* There must be a zero-parameter declaration */
and exists ( FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() | fde.getNumberOfParameters() = 0)
/* There must be a mismatch between number of call arguments and number of parameters in some
- * non-implicit declaration of Function f
+ * 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
+ and exists ( FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() | fde.getNumberOfParameters() != fc.getNumberOfArguments())
+ /* There must be no actual declaration of Function f whose number of parameters matches number of call arguments */
+ and not exists ( FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() | not fde.isImplicit() and fde.getNumberOfParameters() = fc.getNumberOfArguments())
+select fc, "This call has arguments, but $@ is not declared with any parameters.", f, f.toString()
\ No newline at end of file
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/FutileParams.expected b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/FutileParams.expected
index 4bb782dfd11d..0021164c8614 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/FutileParams.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/FutileParams.expected
@@ -1,4 +1,6 @@
-| 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 |
+| test.c:7:3:7: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:12:3:12:12 | call to undeclared | This call has arguments, but $@ is not declared with any parameters. | test.c:11:3:11:3 | undeclared | undeclared |
+| 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:17:3:17:29 | call to declared_empty_defined_with | This call has arguments, but $@ is not declared with any parameters. | test.c:27:6:27:32 | declared_empty_defined_with | declared_empty_defined_with |
+| test.c:22:3:22:29 | call to declared_empty_defined_with | This call has arguments, but $@ is not declared with any parameters. | test.c:27:6:27:32 | declared_empty_defined_with | declared_empty_defined_with |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/test.c b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/test.c
index ef81c416343a..698644c5c1cf 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/test.c
+++ b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/test.c
@@ -8,10 +8,8 @@ void test() {
declared_void(); // GOOD
declared_with(1); // GOOD
- declared_ellipsis(); // GOOD
- declared_ellipsis(2); // GOOD
-
- undeclared(1); // GOOD
+ undeclared(); // GOOD
+ undeclared(1); // BAD
not_yet_declared1(1); // BAD
not_yet_declared2(1); // GOOD
From 5a092d0fed30060097c191055adddcd9a385e403 Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Wed, 20 Mar 2019 19:42:51 -0700
Subject: [PATCH 04/27] [CPP-340] Create three QL queries: (1) mismatched
argument types, (2) too few arguments and (3) too many arguments.
Create new 'UnderspecifiedFunction' folders for both queries and tests.
---
.../Likely Bugs/Likely Typos/FutileParams.c | 11 ------
.../Likely Typos/FutileParams.qhelp | 36 -------------------
.../Likely Bugs/Likely Typos/FutileParams.ql | 27 --------------
.../MistypedFunctionArguments.c | 8 +++++
.../MistypedFunctionArguments.qhelp | 29 +++++++++++++++
.../MistypedFunctionArguments.ql | 30 ++++++++++++++++
.../UnderspecifiedFunctions/TooFewArguments.c | 8 +++++
.../TooFewArguments.qhelp | 35 ++++++++++++++++++
.../TooFewArguments.ql | 30 ++++++++++++++++
.../TooManyArguments.c | 9 +++++
.../TooManyArguments.qhelp | 30 ++++++++++++++++
.../TooManyArguments.ql | 29 +++++++++++++++
.../FutileParams/FutileParams.expected | 6 ----
.../FutileParams/FutileParams.qlref | 1 -
.../MistypedFunctionArguments.expected | 4 +++
.../MistypedFunctionArguments.qlref | 1 +
.../TooFewArguments.expected | 3 ++
.../TooFewArguments.qlref | 1 +
.../TooManyArguments.expected | 5 +++
.../TooManyArguments.qlref | 1 +
.../test.c | 11 ++++--
.../test.cpp | 0
22 files changed, 232 insertions(+), 83 deletions(-)
delete mode 100644 cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.c
delete mode 100644 cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.qhelp
delete mode 100644 cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.ql
create mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.c
create mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.qhelp
create mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.ql
create mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.c
create mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qhelp
create mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.ql
create mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.c
create mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.qhelp
create mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.ql
delete mode 100644 cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/FutileParams.expected
delete mode 100644 cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/FutileParams.qlref
create mode 100644 cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.expected
create mode 100644 cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.qlref
create mode 100644 cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.expected
create mode 100644 cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qlref
create mode 100644 cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.expected
create mode 100644 cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.qlref
rename cpp/ql/test/query-tests/Likely Bugs/{Likely Typos/FutileParams => UnderspecifiedFunctions}/test.c (62%)
rename cpp/ql/test/query-tests/Likely Bugs/{Likely Typos/FutileParams => UnderspecifiedFunctions}/test.cpp (100%)
diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.c b/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.c
deleted file mode 100644
index 1a827a6c90a3..000000000000
--- a/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.c
+++ /dev/null
@@ -1,11 +0,0 @@
-void no_argument();
-
-void one_argument(int x);
-
-void calls() {
- no_argument(1) // BAD: `no_argument` will accept and ignore the argument
-
- one_argument(1); // GOOD: `one_argument` will accept and use the argument
-
- no_argument(); // GOOD: `no_argument` has not been passed an argument
-}
\ No newline at end of file
diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.qhelp b/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.qhelp
deleted file mode 100644
index 0c1e345c04fa..000000000000
--- a/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.qhelp
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
-
-A function is called with arguments despite having been declared with an empty parameter list.
-In addition, we were either unable to find a definition of the function, or found one with
-an incompatible number of parameters.
-
-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.
-
-In C, a function declared with an empty parameter list () 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 (void) as the parameter list in any forward declarations.
-In C++, () means the same as (void), i.e., indicates that the function accepts no
-arguments.
-
-
-
-Call the function without arguments, or call a different function that expects the arguments
-being passed. If possible, change the forward declaration of the ()-function to reflect the
-arguments being passed, or change the () to (void) to indicate that no arguments
-shall be passed.
-
-
-
-
-
-
-
-SEI CERT C++ Coding Standard: DCL20-C. Explicitly specify void when a function accepts no arguments
-
-
diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.ql b/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.ql
deleted file mode 100644
index c21afaf4ac9a..000000000000
--- a/cpp/ql/src/Likely Bugs/Likely Typos/FutileParams.ql
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * @name Non-empty call to function declared without parameters
- * @description A call to a function declared without parameters has arguments, which may indicate
- * that the code does not follow the author's intent.
- * @kind problem
- * @problem.severity warning
- * @precision very-high
- * @id cpp/futile-params
- * @tags correctness
- * maintainability
- */
-
-import cpp
-
-from FunctionCall fc, Function f
- where f = fc.getTarget() and not f.isVarargs()
- /* There must be a zero-parameter declaration */
- and exists ( FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() | fde.getNumberOfParameters() = 0)
- /* There must be a mismatch between number of call arguments and number of parameters in some
- * declaration of Function f
- */
- and exists ( FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() | fde.getNumberOfParameters() != fc.getNumberOfArguments())
- /* There must be no actual declaration of Function f whose number of parameters matches number of call arguments */
- and not exists ( FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() | not fde.isImplicit() and fde.getNumberOfParameters() = fc.getNumberOfArguments())
-select fc, "This call has arguments, but $@ is not declared with any parameters.", f, f.toString()
-
-
\ No newline at end of file
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.c b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.c
new file mode 100644
index 000000000000..faff73f64fba
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.c
@@ -0,0 +1,8 @@
+void no_argument();
+
+void three_arguments(int x, int y, int z);
+
+void calls() {
+ three_arguments(1, 2, 3); // GOOD
+ three_arguments(1.0f, 2, 3.0f); // BAD: arguments 1 and 3 do not match parameters
+}
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.qhelp b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.qhelp
new file mode 100644
index 000000000000..f4bdb7d11d4a
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.qhelp
@@ -0,0 +1,29 @@
+
+
+
+
+
+A function is called with at least one argument whose type is incompatible with the type of
+ the corresponding parameter of the function being called. This may cause the called function
+ to behave unpredictably.
+
+This may indicate that an incorrect function is being called, or that the
+ signature (parameter list and parameter types) of the called function
+ is not known to the author.
+
+
+
+Call the function with the proper argument types. In some cases, it may
+ suffice to provide an explicit cast of an argument to the desired (parameter) type.
+
+
+
+
+
+
+
+SEI CERT C++ Coding Standard: DCL20-C. Explicitly specify void when a function accepts no arguments
+
+
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.ql b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.ql
new file mode 100644
index 000000000000..c193a835e929
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.ql
@@ -0,0 +1,30 @@
+/**
+ * @name Call to a function with one or more incompatible arguments
+ * @description A call to a function with at least one argument whose type does
+ * not match the type of the corresponding function parameter. This may indicate
+ * that the author is not familiar with the function being called. Passing mistyped
+ * arguments on a stack may lead to unpredictable function behavior.
+ * @kind problem
+ * @problem.severity warning
+ * @precision very-high
+ * @id cpp/mistyped-function-arguments
+ * @tags correctness
+ * maintainability
+ */
+
+import cpp
+
+from FunctionCall fc, Function f, Parameter p
+where
+ f = fc.getTarget() and
+ p = f.getAParameter() and
+ not f.isVarargs() and
+ p.getIndex() < fc.getNumberOfArguments() and
+ // There must be a zero-parameter declaration
+ exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
+ fde.getNumberOfParameters() = 0
+ ) and
+ // Parameter p and its corresponding call argument must have mismatched types
+ p.getType() != fc.getArgument(p.getIndex()).getType()
+select fc, "Calling $@: $@ is incompatible with $@.", f, f.toString(), fc.getArgument(p.getIndex()),
+ fc.getArgument(p.getIndex()).toString(), p, p.getTypedName()
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.c b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.c
new file mode 100644
index 000000000000..246d029e5480
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.c
@@ -0,0 +1,8 @@
+
+void one_argument(int x);
+
+void calls() {
+ one_argument(1); // GOOD: `one_argument` will accept and use the argument
+
+ one_argument(); // BAD: `one_argument` will receive an undefined value
+}
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qhelp b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qhelp
new file mode 100644
index 000000000000..8eb266e3ac3a
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qhelp
@@ -0,0 +1,35 @@
+
+
+
+
+
+A function is called with fewer arguments than there are parameters of the function.
+
+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.
+
+In C, function calls generally need to provide the same number of arguments as there are
+ arguments to the function. (Variadic functions can accept additional arguments.) Providing
+ fewer arguments than there are parameters is extremely dangerous, as the called function
+ will nevertheless try to obtain the missing arguments' values, either from the stack
+ or from machine registers. As a result, the function may behave unpredictably.
+
+If the called function modifies a parameter corresponding to a missing argument, it
+ may alter the state of the program upon its return. An attacker could use this to,
+ for example, alter the control flow of the program to access forbidden resources.
+
+
+
+Call the function with the correct number of arguments.
+
+
+
+
+
+
+
+SEI CERT C++ Coding Standard: DCL20-C. Explicitly specify void when a function accepts no arguments
+
+
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.ql b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.ql
new file mode 100644
index 000000000000..04ccc86d0929
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.ql
@@ -0,0 +1,30 @@
+/**
+ * @name Call to function with fewer arguments than declared parameters
+ * @description A function call passed fewer arguments than the number of
+ * declared parameters of the function. This may indicate
+ * that the code does not follow the author's intent. It is also a vulnerability,
+ * since the function is like to operate on undefined data.
+ * @kind problem
+ * @problem.severity error
+ * @precision very-high
+ * @id cpp/too-few-arguments
+ * @tags correctness
+ * maintainability
+ */
+
+import cpp
+
+from FunctionCall fc, Function f
+where
+ f = fc.getTarget() and
+ not f.isVarargs() and
+ // There must be a zero-parameter declaration (explicit or implicit)
+ exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
+ fde.getNumberOfParameters() = 0
+ ) and
+ // There is an explicit declaration of the function whose parameter count is larger
+ // than the number of call arguments
+ exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
+ not fde.isImplicit() and fde.getNumberOfParameters() > fc.getNumberOfArguments()
+ )
+select fc, "This call has fewer arguments than required by $@.", f, f.toString()
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.c b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.c
new file mode 100644
index 000000000000..2ab318f70765
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.c
@@ -0,0 +1,9 @@
+
+void one_argument(int x);
+
+void calls() {
+
+ one_argument(1); // GOOD: `one_argument` will accept and use the argument
+
+ one_argument(1, 2); // BAD: `one_argument` will use the first argument but ignore the second
+}
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.qhelp b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.qhelp
new file mode 100644
index 000000000000..a473a1b16445
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.qhelp
@@ -0,0 +1,30 @@
+
+
+
+
+
+A function is called with more arguments than there are parameters of the function.
+
+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.
+
+In C, function calls generally need to provide the same number of arguments as there are
+ arguments to the function. (Variadic functions can accept additional arguments.) Providing
+ more arguments than there are parameters incurs an unneeded computational overhead, both
+ in terms of time and of additional stack space.
+
+
+
+Call the function with the correct number of arguments.
+
+
+
+
+
+
+
+SEI CERT C++ Coding Standard: DCL20-C. Explicitly specify void when a function accepts no arguments
+
+
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.ql b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.ql
new file mode 100644
index 000000000000..e58a64caab95
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.ql
@@ -0,0 +1,29 @@
+/**
+ * @name Call to function with extraneous parameters
+ * @description A function call to a function passed more arguments than there are
+ * declared parameters of the function. This may indicate
+ * that the code does not follow the author's intent.
+ * @kind problem
+ * @problem.severity warning
+ * @precision very-high
+ * @id cpp/too-many-arguments
+ * @tags correctness
+ * maintainability
+ */
+
+import cpp
+
+from FunctionCall fc, Function f
+where
+ f = fc.getTarget() and
+ not f.isVarargs() and
+ // There must be a zero-parameter declaration (explicit or implicit)
+ exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
+ fde.getNumberOfParameters() = 0
+ ) and
+ // There must not exist a declaration with the number of parameters
+ // at least as large as the number of call arguments
+ not exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
+ fde.getNumberOfParameters() >= fc.getNumberOfArguments()
+ )
+select fc, "This call has more arguments than required by $@.", f, f.toString()
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/FutileParams.expected b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/FutileParams.expected
deleted file mode 100644
index 0021164c8614..000000000000
--- a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/FutileParams.expected
+++ /dev/null
@@ -1,6 +0,0 @@
-| test.c:7:3:7: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:12:3:12:12 | call to undeclared | This call has arguments, but $@ is not declared with any parameters. | test.c:11:3:11:3 | undeclared | undeclared |
-| 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:17:3:17:29 | call to declared_empty_defined_with | This call has arguments, but $@ is not declared with any parameters. | test.c:27:6:27:32 | declared_empty_defined_with | declared_empty_defined_with |
-| test.c:22:3:22:29 | call to declared_empty_defined_with | This call has arguments, but $@ is not declared with any parameters. | test.c:27:6:27:32 | declared_empty_defined_with | declared_empty_defined_with |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/FutileParams.qlref b/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/FutileParams.qlref
deleted file mode 100644
index f6dbe907dc59..000000000000
--- a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/FutileParams.qlref
+++ /dev/null
@@ -1 +0,0 @@
-Likely Bugs/Likely Typos/FutileParams.ql
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.expected
new file mode 100644
index 000000000000..7097b643f4e3
--- /dev/null
+++ b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.expected
@@ -0,0 +1,4 @@
+| test.c:23:3:23:29 | call to declared_empty_defined_with | Calling $@: $@ is incompatible with $@. | test.c:31:6:31:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:23:31:23:32 | & ... | & ... | test.c:31:38:31:38 | x | int x |
+| test.c:24:3:24:29 | call to declared_empty_defined_with | Calling $@: $@ is incompatible with $@. | test.c:31:6:31:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:24:31:24:34 | 3.0 | 3.0 | test.c:31:38:31:38 | x | int x |
+| test.c:26:3:26:27 | call to not_declared_defined_with | Calling $@: $@ is incompatible with $@. | test.c:34:6:34:30 | not_declared_defined_with | not_declared_defined_with | test.c:26:29:26:31 | 1.0 | 1.0 | test.c:34:36:34:36 | x | int x |
+| test.c:26:3:26:27 | call to not_declared_defined_with | Calling $@: $@ is incompatible with $@. | test.c:34:6:34:30 | not_declared_defined_with | not_declared_defined_with | test.c:26:37:26:38 | 2 | 2 | test.c:34:50:34:50 | z | int z |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.qlref b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.qlref
new file mode 100644
index 000000000000..e61361d6bfee
--- /dev/null
+++ b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.qlref
@@ -0,0 +1 @@
+Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.expected
new file mode 100644
index 000000000000..cf232973ba35
--- /dev/null
+++ b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.expected
@@ -0,0 +1,3 @@
+| test.c:17:3:17:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:16:3:16:3 | not_yet_declared2 | not_yet_declared2 |
+| test.c:17:3:17:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:30:6:30:22 | not_yet_declared2 | not_yet_declared2 |
+| test.c:19:3:19:29 | call to declared_empty_defined_with | This call has fewer arguments than required by $@. | test.c:31:6:31:32 | declared_empty_defined_with | declared_empty_defined_with |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qlref b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qlref
new file mode 100644
index 000000000000..710092c54d85
--- /dev/null
+++ b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qlref
@@ -0,0 +1 @@
+Likely Bugs/Underspecified Functions/TooFewArguments.ql
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.expected
new file mode 100644
index 000000000000..319d92628a02
--- /dev/null
+++ b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.expected
@@ -0,0 +1,5 @@
+| test.c:8:3:8:16 | call to declared_empty | This call has more arguments than required by $@. | test.c:1:6:1:19 | declared_empty | declared_empty |
+| test.c:13:3:13:12 | call to undeclared | This call has more arguments than required by $@. | test.c:12:3:12:3 | undeclared | undeclared |
+| test.c:15:3:15:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:15:3:15:3 | not_yet_declared1 | not_yet_declared1 |
+| test.c:15:3:15:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:29:6:29:22 | not_yet_declared1 | not_yet_declared1 |
+| test.c:24:3:24:29 | call to declared_empty_defined_with | This call has more arguments than required by $@. | test.c:31:6:31:32 | declared_empty_defined_with | declared_empty_defined_with |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.qlref b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.qlref
new file mode 100644
index 000000000000..ca44af39c2bf
--- /dev/null
+++ b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.qlref
@@ -0,0 +1 @@
+Likely Bugs/Underspecified Functions/TooManyArguments.ql
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/test.c b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/test.c
similarity index 62%
rename from cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/test.c
rename to cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/test.c
index 698644c5c1cf..90247dde0ff4 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/test.c
+++ b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/test.c
@@ -1,6 +1,7 @@
void declared_empty();
void declared_void(void);
void declared_with(int);
+void declared_empty_defined_with();
void test() {
declared_empty(); // GOOD
@@ -13,13 +14,16 @@ void test() {
not_yet_declared1(1); // BAD
not_yet_declared2(1); // GOOD
+ not_yet_declared2(); // BAD
declared_empty_defined_with(); // BAD
declared_empty_defined_with(1); // GOOD
int x;
- declared_empty_defined_with(&x); // GOOD
- declared_empty_defined_with(x, x); // BAD
+ declared_empty_defined_with(&x); // GOOD (type mismatch)
+ declared_empty_defined_with(3.0f, &x); // BAD (type mismatch)
+
+ not_declared_defined_with(1.0, 0, 2U); // GOOD (type mismatch)
}
void not_yet_declared1();
@@ -27,3 +31,6 @@ void not_yet_declared2(int);
void declared_empty_defined_with(int x) {
// do nothing
}
+void not_declared_defined_with(int x, int y, int z) {
+ return;
+}
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/test.cpp b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/test.cpp
similarity index 100%
rename from cpp/ql/test/query-tests/Likely Bugs/Likely Typos/FutileParams/test.cpp
rename to cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/test.cpp
From 29af56d21b7fe74bc8560274d4ea43485c2e2911 Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Sun, 24 Mar 2019 19:42:05 -0700
Subject: [PATCH 05/27] [CPP-340] Refine the test query for mismatching
args/params by applying C promotion rules. The following issues
are now flagged: (1) passing a larger type than the receiver can
accept (e.g., long long -> int) (2) passing a
type of different signedness than the parameter specified.
---
.../MistypedFunctionArguments.ql | 93 ++++++++++++++++++-
.../TooFewArguments.ql | 1 +
.../MistypedFunctionArguments.expected | 8 +-
.../MistypedFunctionArguments.qlref | 2 +-
.../TooFewArguments.expected | 4 +-
.../TooFewArguments.qlref | 2 +-
.../TooManyArguments.expected | 4 +-
.../TooManyArguments.qlref | 2 +-
.../UnderspecifiedFunctions/test.c | 1 +
9 files changed, 103 insertions(+), 14 deletions(-)
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.ql b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.ql
index c193a835e929..a850c0612e45 100644
--- a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.ql
+++ b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.ql
@@ -14,6 +14,91 @@
import cpp
+predicate argTypeMayBePromoted(Type arg, Type parm) {
+ arg = parm
+ or
+ // floating-point and integral promotions
+ arg instanceof FloatType and parm instanceof DoubleType
+ or
+ arg instanceof FloatType and parm instanceof LongDoubleType
+ or
+ arg instanceof DoubleType and parm instanceof LongDoubleType
+ or
+ arg instanceof CharType and parm instanceof IntType
+ or
+ arg instanceof CharType and parm instanceof IntType
+ or
+ arg instanceof CharType and parm instanceof LongType
+ or
+ arg instanceof CharType and parm instanceof LongLongType
+ or
+ arg instanceof ShortType and parm instanceof IntType
+ or
+ arg instanceof ShortType and parm instanceof LongType
+ or
+ arg instanceof ShortType and parm instanceof LongLongType
+ or
+ arg instanceof IntType and parm instanceof LongType
+ or
+ arg instanceof IntType and parm instanceof LongLongType
+ or
+ arg instanceof LongType and parm instanceof LongLongType
+ or
+ arg instanceof Enum and parm instanceof IntType
+ or
+ arg instanceof Enum and parm instanceof LongType
+ or
+ arg instanceof Enum and parm instanceof LongLongType
+ or
+ // enums are usually sized as ints
+ arg instanceof IntType and parm instanceof Enum
+ or
+ // pointer types
+ arg.(PointerType).getBaseType().getUnspecifiedType() = parm
+ .getUnspecifiedType()
+ .(PointerType)
+ .getBaseType()
+ .getUnspecifiedType()
+ or
+ // void * parameters accept arbitrary pointer arguments
+ arg instanceof PointerType and
+ parm.(PointerType).getBaseType().getUnspecifiedType() instanceof VoidType
+ or
+ // handle reference types
+ argTypeMayBePromoted(arg.(ReferenceType).getBaseType().getUnspecifiedType(), parm)
+ or
+ argTypeMayBePromoted(arg, parm.(ReferenceType).getBaseType().getUnspecifiedType())
+ or
+ // array-to-pointer decay
+ argTypeMayBePromoted(arg.(ArrayType).getBaseType().getUnspecifiedType(),
+ parm.(PointerType).getBaseType().getUnspecifiedType())
+ or
+ // pointer-to-array promotion (C99)
+ argTypeMayBePromoted(arg.(PointerType).getBaseType().getUnspecifiedType(),
+ parm.(ArrayType).getBaseType().getUnspecifiedType())
+}
+
+// This predicate doesn't necessarily have to exist, but if it does exist
+// then it must be inline to make sure we don't enumerate all pairs of
+// compatible types.
+// Its body could also just be hand-inlined where it's used.
+pragma[inline]
+predicate argMayBePromoted(Expr arg, Parameter parm) {
+ argTypeMayBePromoted(arg.getExplicitlyConverted().getType().getUnspecifiedType(),
+ parm.getType().getUnspecifiedType())
+ or
+ // The value 0 is often passed in to indicate NULL, or to initialize an arbitrary integer type.
+ // we will allow all literal values for simplicity. Pointer parameters are sometime passed
+ // special-case literals such as -1, -2, etc.
+ arg.(Literal).getType() instanceof IntegralType and
+ (
+ parm.getType().getUnspecifiedType() instanceof PointerType
+ or
+ parm.getType().getUnspecifiedType() instanceof IntegralType and
+ arg.(Literal).getType().getSize() <= parm.getType().getUnspecifiedType().getSize()
+ )
+}
+
from FunctionCall fc, Function f, Parameter p
where
f = fc.getTarget() and
@@ -25,6 +110,8 @@ where
fde.getNumberOfParameters() = 0
) and
// Parameter p and its corresponding call argument must have mismatched types
- p.getType() != fc.getArgument(p.getIndex()).getType()
-select fc, "Calling $@: $@ is incompatible with $@.", f, f.toString(), fc.getArgument(p.getIndex()),
- fc.getArgument(p.getIndex()).toString(), p, p.getTypedName()
+ not argMayBePromoted(fc.getArgument(p.getIndex()), p)
+select fc, "Calling $@: argument $@ of type $@ is incompatible with parameter $@.", f, f.toString(),
+ fc.getArgument(p.getIndex()), fc.getArgument(p.getIndex()).toString(),
+ fc.getArgument(p.getIndex()).getType(), fc.getArgument(p.getIndex()).getType().toString(), p,
+ p.getTypedName()
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.ql b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.ql
index 04ccc86d0929..2a7b9a0e7ab0 100644
--- a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.ql
+++ b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.ql
@@ -10,6 +10,7 @@
* @id cpp/too-few-arguments
* @tags correctness
* maintainability
+ * security
*/
import cpp
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.expected
index 7097b643f4e3..aa962619687a 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.expected
@@ -1,4 +1,4 @@
-| test.c:23:3:23:29 | call to declared_empty_defined_with | Calling $@: $@ is incompatible with $@. | test.c:31:6:31:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:23:31:23:32 | & ... | & ... | test.c:31:38:31:38 | x | int x |
-| test.c:24:3:24:29 | call to declared_empty_defined_with | Calling $@: $@ is incompatible with $@. | test.c:31:6:31:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:24:31:24:34 | 3.0 | 3.0 | test.c:31:38:31:38 | x | int x |
-| test.c:26:3:26:27 | call to not_declared_defined_with | Calling $@: $@ is incompatible with $@. | test.c:34:6:34:30 | not_declared_defined_with | not_declared_defined_with | test.c:26:29:26:31 | 1.0 | 1.0 | test.c:34:36:34:36 | x | int x |
-| test.c:26:3:26:27 | call to not_declared_defined_with | Calling $@: $@ is incompatible with $@. | test.c:34:6:34:30 | not_declared_defined_with | not_declared_defined_with | test.c:26:37:26:38 | 2 | 2 | test.c:34:50:34:50 | z | int z |
+| test.c:23:3:23:29 | call to declared_empty_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:32:6:32:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:23:31:23:32 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:32:38:32:38 | x | int x |
+| test.c:24:3:24:29 | call to declared_empty_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:32:6:32:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:24:31:24:34 | 3.0 | 3.0 | file://:0:0:0:0 | float | float | test.c:32:38:32:38 | x | int x |
+| test.c:26:3:26:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:35:6:35:30 | not_declared_defined_with | not_declared_defined_with | test.c:26:29:26:31 | 1.0 | 1.0 | file://:0:0:0:0 | double | double | test.c:35:36:35:36 | x | int x |
+| test.c:27:3:27:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:35:6:35:30 | not_declared_defined_with | not_declared_defined_with | test.c:27:29:27:31 | 4 | 4 | file://:0:0:0:0 | long long | long long | test.c:35:36:35:36 | x | int x |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.qlref b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.qlref
index e61361d6bfee..e2e24d78bc38 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.qlref
+++ b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.qlref
@@ -1 +1 @@
-Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
+Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.ql
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.expected
index cf232973ba35..ac56c76fb3cc 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.expected
@@ -1,3 +1,3 @@
| test.c:17:3:17:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:16:3:16:3 | not_yet_declared2 | not_yet_declared2 |
-| test.c:17:3:17:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:30:6:30:22 | not_yet_declared2 | not_yet_declared2 |
-| test.c:19:3:19:29 | call to declared_empty_defined_with | This call has fewer arguments than required by $@. | test.c:31:6:31:32 | declared_empty_defined_with | declared_empty_defined_with |
+| test.c:17:3:17:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:31:6:31:22 | not_yet_declared2 | not_yet_declared2 |
+| test.c:19:3:19:29 | call to declared_empty_defined_with | This call has fewer arguments than required by $@. | test.c:32:6:32:32 | declared_empty_defined_with | declared_empty_defined_with |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qlref b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qlref
index 710092c54d85..cfc3bd165a23 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qlref
+++ b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qlref
@@ -1 +1 @@
-Likely Bugs/Underspecified Functions/TooFewArguments.ql
+Likely Bugs/UnderspecifiedFunctions/TooFewArguments.ql
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.expected
index 319d92628a02..06c5439ecc64 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.expected
@@ -1,5 +1,5 @@
| test.c:8:3:8:16 | call to declared_empty | This call has more arguments than required by $@. | test.c:1:6:1:19 | declared_empty | declared_empty |
| test.c:13:3:13:12 | call to undeclared | This call has more arguments than required by $@. | test.c:12:3:12:3 | undeclared | undeclared |
| test.c:15:3:15:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:15:3:15:3 | not_yet_declared1 | not_yet_declared1 |
-| test.c:15:3:15:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:29:6:29:22 | not_yet_declared1 | not_yet_declared1 |
-| test.c:24:3:24:29 | call to declared_empty_defined_with | This call has more arguments than required by $@. | test.c:31:6:31:32 | declared_empty_defined_with | declared_empty_defined_with |
+| test.c:15:3:15:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:30:6:30:22 | not_yet_declared1 | not_yet_declared1 |
+| test.c:24:3:24:29 | call to declared_empty_defined_with | This call has more arguments than required by $@. | test.c:32:6:32:32 | declared_empty_defined_with | declared_empty_defined_with |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.qlref b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.qlref
index ca44af39c2bf..9438d5ad537b 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.qlref
+++ b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.qlref
@@ -1 +1 @@
-Likely Bugs/Underspecified Functions/TooManyArguments.ql
+Likely Bugs/UnderspecifiedFunctions/TooManyArguments.ql
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/test.c b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/test.c
index 90247dde0ff4..0fa1097fc119 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/test.c
+++ b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/test.c
@@ -24,6 +24,7 @@ void test() {
declared_empty_defined_with(3.0f, &x); // BAD (type mismatch)
not_declared_defined_with(1.0, 0, 2U); // GOOD (type mismatch)
+ not_declared_defined_with(4LL, 0, 2); // GOOD (type mismatch)
}
void not_yet_declared1();
From cb5bbd219764f5c70ce8e94360a5e13031176377 Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Fri, 29 Mar 2019 20:19:45 -0700
Subject: [PATCH 06/27] [CPP-340] When warning about mismatched parameters,
follow what C compilers do. Various integral and floating-point
types are treated as mutually implicitly convertible. Remaining
warnings deal with misuse of pointer and array types.
---
.../MistypedFunctionArguments.c | 7 +-
.../MistypedFunctionArguments.o | Bin 0 -> 1720 bytes
.../MistypedFunctionArguments.ql | 93 ++++++------------
.../MistypedFunctionArguments.s | 1 +
.../TooFewArguments.ql | 2 +-
.../TooManyArguments.c | 5 +-
.../TooManyArguments.qhelp | 2 +-
.../UnderspecifiedFunctions/tests.c | 33 +++++++
.../MistypedFunctionArguments.expected | 11 ++-
.../TooFewArguments.expected | 7 +-
.../TooManyArguments.expected | 10 +-
.../UnderspecifiedFunctions/test.c | 34 ++++++-
12 files changed, 117 insertions(+), 88 deletions(-)
create mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.o
create mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.s
create mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/tests.c
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.c b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.c
index faff73f64fba..fa3235a6e3fe 100644
--- a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.c
+++ b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.c
@@ -1,8 +1,7 @@
-void no_argument();
-
void three_arguments(int x, int y, int z);
void calls() {
- three_arguments(1, 2, 3); // GOOD
- three_arguments(1.0f, 2, 3.0f); // BAD: arguments 1 and 3 do not match parameters
+ int three = 3;
+ three_arguments(1, 2, three); // GOOD
+ three_arguments(1, 2, &three); // BAD
}
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.o b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.o
new file mode 100644
index 0000000000000000000000000000000000000000..5d4064e871cbf611b42cb07aa3896e8bf85112c5
GIT binary patch
literal 1720
zcmb`HPiqrV5Wr`%+N!ORiU*+z>qR5lM^c5BqLMV^50Vw@6F8Hoqd~^l}0tAX~3ev9XN`Z
z0=(Cc{9@=9VHRefRp0;ef!01|@bZaDztZx5V$?M3SATPSyzTzykRLoggj%`0V&q!w
zz?FfqByNcO!s1d8hK0StvdG`O8e!~kj=G>|&mVxclhx*Dr%xQr8C*r
zneyqW%pPVCNEdqGWAI~`wyLL25~$_!`Nkd0uN_3wssMtIrur`9oSw%
zel~WW;j<&Vf|^B5%54N`9M-mcx%<@VR0G$RTLZV`Z3cbEmAch&qxn5drR7{Xv&v8tPD`-!CPjsI%sK17hKMPWhxG5&mvpT5S-%^dj43&vSZ~kj{<-(XpfjqV4-2>_MOA1;QOjN7U}M
z7JO;h+aSVpr)xg(tiChq|BsG=^>lWVC##5zgwH_~MY-&gokyj2P(+Q(TQ!7t3Z6tu
z`|u}pUh&I{C%=S4wVpK8BQDo5pq_tQU%*=GnMaKa?|&^0(dYfyuEbb8^;chO0ke^CvD=S=gbe+jN
-SEI CERT C++ Coding Standard: DCL20-C. Explicitly specify void when a function accepts no arguments
+SEI CERT C Coding Standard: DCL20-C. Explicitly specify void when a function accepts no arguments
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/tests.c b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/tests.c
new file mode 100644
index 000000000000..3c44536ac622
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/tests.c
@@ -0,0 +1,33 @@
+//void three_arguments();
+void three_arguments(int x, char y, int *z);
+void pointer_arguments(float *x, void *y, int **z);
+void array_argument(int arr[6]);
+void array_argument2(char arr[6]);
+int var;
+void *pv;
+double d = 3732.70e13L;
+extern unsigned long long *ull;
+
+extern void *a[3];
+
+void calls() {
+ three_arguments(*ull, 2, &var); // BAD: arguments 1 and 3 do not match parameters
+ three_arguments(&ull, 2, &var); // BAD: arguments 1 and 3 do not match parameters
+ three_arguments(&var, 2, &var); // BAD: arguments 1 and 3 do not match parameters
+ three_arguments(var, 2, 3.0f); // BAD: arguments 1 and 3 do not match parameters
+
+ pointer_arguments(20, 0, 0); // BAD
+ pointer_arguments(pv, &var, &pv); // GOOD
+ pointer_arguments(&pv, &var, pv); // BAD
+ pointer_arguments(&var, a, &pv); // BAD
+ pointer_arguments(&var, &pv, a); // BAD
+
+ array_argument(&var);
+ array_argument(pv);
+ array_argument(10);
+ array_argument("Hello");
+
+ array_argument2("Hello");
+
+}
+
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.expected
index aa962619687a..a8ce8fe0506c 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.expected
@@ -1,4 +1,7 @@
-| test.c:23:3:23:29 | call to declared_empty_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:32:6:32:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:23:31:23:32 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:32:38:32:38 | x | int x |
-| test.c:24:3:24:29 | call to declared_empty_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:32:6:32:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:24:31:24:34 | 3.0 | 3.0 | file://:0:0:0:0 | float | float | test.c:32:38:32:38 | x | int x |
-| test.c:26:3:26:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:35:6:35:30 | not_declared_defined_with | not_declared_defined_with | test.c:26:29:26:31 | 1.0 | 1.0 | file://:0:0:0:0 | double | double | test.c:35:36:35:36 | x | int x |
-| test.c:27:3:27:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:35:6:35:30 | not_declared_defined_with | not_declared_defined_with | test.c:27:29:27:31 | 4 | 4 | file://:0:0:0:0 | long long | long long | test.c:35:36:35:36 | x | int x |
+| test.c:25:3:25:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:24:3:24:3 | not_yet_declared2 | not_yet_declared2 | test.c:25:21:25:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:45:24:45:26 | p#0 | int p#0 |
+| test.c:25:3:25:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:45:6:45:22 | not_yet_declared2 | not_yet_declared2 | test.c:25:21:25:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:45:24:45:26 | p#0 | int p#0 |
+| test.c:32:3:32:29 | call to declared_empty_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:46:6:46:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:32:31:32:32 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:46:38:46:38 | x | int x |
+| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:39:26:39:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:61:34:61:34 | x | int * x |
+| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:61:6:61:27 | declared_with_pointers | declared_with_pointers | test.c:39:26:39:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:61:34:61:34 | x | int * x |
+| test.c:41:3:41:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:6:6:6:24 | declared_with_array | declared_with_array | test.c:41:23:41:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:62:31:62:31 | a | char[6] a |
+| test.c:41:3:41:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:62:6:62:24 | declared_with_array | declared_with_array | test.c:41:23:41:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:62:31:62:31 | a | char[6] a |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.expected
index ac56c76fb3cc..6b56644df7ca 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.expected
@@ -1,3 +1,4 @@
-| test.c:17:3:17:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:16:3:16:3 | not_yet_declared2 | not_yet_declared2 |
-| test.c:17:3:17:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:31:6:31:22 | not_yet_declared2 | not_yet_declared2 |
-| test.c:19:3:19:29 | call to declared_empty_defined_with | This call has fewer arguments than required by $@. | test.c:32:6:32:32 | declared_empty_defined_with | declared_empty_defined_with |
+| test.c:26:3:26:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:24:3:24:3 | not_yet_declared2 | not_yet_declared2 |
+| test.c:26:3:26:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:45:6:45:22 | not_yet_declared2 | not_yet_declared2 |
+| test.c:28:3:28:29 | call to declared_empty_defined_with | This call has fewer arguments than required by $@. | test.c:46:6:46:32 | declared_empty_defined_with | declared_empty_defined_with |
+| test.c:56:10:56:20 | call to dereference | This call has fewer arguments than required by $@. | test.c:59:5:59:15 | dereference | dereference |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.expected
index 06c5439ecc64..89ae7d04771e 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.expected
@@ -1,5 +1,5 @@
-| test.c:8:3:8:16 | call to declared_empty | This call has more arguments than required by $@. | test.c:1:6:1:19 | declared_empty | declared_empty |
-| test.c:13:3:13:12 | call to undeclared | This call has more arguments than required by $@. | test.c:12:3:12:3 | undeclared | undeclared |
-| test.c:15:3:15:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:15:3:15:3 | not_yet_declared1 | not_yet_declared1 |
-| test.c:15:3:15:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:30:6:30:22 | not_yet_declared1 | not_yet_declared1 |
-| test.c:24:3:24:29 | call to declared_empty_defined_with | This call has more arguments than required by $@. | test.c:32:6:32:32 | declared_empty_defined_with | declared_empty_defined_with |
+| test.c:16:3:16:16 | call to declared_empty | This call has more arguments than required by $@. | test.c:1:6:1:19 | declared_empty | declared_empty |
+| test.c:21:3:21:12 | call to undeclared | This call has more arguments than required by $@. | test.c:20:3:20:3 | undeclared | undeclared |
+| test.c:23:3:23:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:23:3:23:3 | not_yet_declared1 | not_yet_declared1 |
+| test.c:23:3:23:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:44:6:44:22 | not_yet_declared1 | not_yet_declared1 |
+| test.c:33:3:33:29 | call to declared_empty_defined_with | This call has more arguments than required by $@. | test.c:46:6:46:32 | declared_empty_defined_with | declared_empty_defined_with |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/test.c b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/test.c
index 0fa1097fc119..16f10479f66c 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/test.c
+++ b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/test.c
@@ -2,6 +2,14 @@ void declared_empty();
void declared_void(void);
void declared_with(int);
void declared_empty_defined_with();
+void declared_with_pointers();
+void declared_with_array();
+
+struct _s { int a, b; } s;
+
+int ca[4] = { 1, 2, 3, 4 };
+
+void *pv;
void test() {
declared_empty(); // GOOD
@@ -14,17 +22,23 @@ void test() {
not_yet_declared1(1); // BAD
not_yet_declared2(1); // GOOD
+ not_yet_declared2(ca); // BAD
not_yet_declared2(); // BAD
declared_empty_defined_with(); // BAD
declared_empty_defined_with(1); // GOOD
int x;
- declared_empty_defined_with(&x); // GOOD (type mismatch)
- declared_empty_defined_with(3.0f, &x); // BAD (type mismatch)
+ declared_empty_defined_with(&x); // BAD
+ declared_empty_defined_with(3.0f, &x); // BAD
- not_declared_defined_with(1.0, 0, 2U); // GOOD (type mismatch)
- not_declared_defined_with(4LL, 0, 2); // GOOD (type mismatch)
+ not_declared_defined_with(1.0, 0, 2U); // GOOD
+ not_declared_defined_with(4LL, 0, 2.5e9); // GOOD
+
+ declared_with_pointers(pv, ca); // GOOD
+ declared_with_pointers(3.5e15, 0); // BAD
+ declared_with_array("Hello"); // GOOD
+ declared_with_array(&x); // BAD
}
void not_yet_declared1();
@@ -35,3 +49,15 @@ void declared_empty_defined_with(int x) {
void not_declared_defined_with(int x, int y, int z) {
return;
}
+
+int dereference();
+
+int caller(void) {
+ return dereference(); // BAD
+}
+
+int dereference(int *x) { return *x; }
+
+void declared_with_pointers(int *x, void *y);
+void declared_with_array(char a [6]);
+
From 2ea9f81c7f1a8c844f1d48b7b0063462a43b949a Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Fri, 29 Mar 2019 20:27:25 -0700
Subject: [PATCH 07/27] [CPP-340] Refer to C coding standard, not C++.
---
.../MistypedFunctionArguments.o | Bin 1720 -> 0 bytes
.../MistypedFunctionArguments.qhelp | 2 +-
.../MistypedFunctionArguments.s | 1 -
.../TooFewArguments.qhelp | 2 +-
.../UnderspecifiedFunctions/tests.c | 33 ------------------
5 files changed, 2 insertions(+), 36 deletions(-)
delete mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.o
delete mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.s
delete mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/tests.c
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.o b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.o
deleted file mode 100644
index 5d4064e871cbf611b42cb07aa3896e8bf85112c5..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1720
zcmb`HPiqrV5Wr`%+N!ORiU*+z>qR5lM^c5BqLMV^50Vw@6F8Hoqd~^l}0tAX~3ev9XN`Z
z0=(Cc{9@=9VHRefRp0;ef!01|@bZaDztZx5V$?M3SATPSyzTzykRLoggj%`0V&q!w
zz?FfqByNcO!s1d8hK0StvdG`O8e!~kj=G>|&mVxclhx*Dr%xQr8C*r
zneyqW%pPVCNEdqGWAI~`wyLL25~$_!`Nkd0uN_3wssMtIrur`9oSw%
zel~WW;j<&Vf|^B5%54N`9M-mcx%<@VR0G$RTLZV`Z3cbEmAch&qxn5drR7{Xv&v8tPD`-!CPjsI%sK17hKMPWhxG5&mvpT5S-%^dj43&vSZ~kj{<-(XpfjqV4-2>_MOA1;QOjN7U}M
z7JO;h+aSVpr)xg(tiChq|BsG=^>lWVC##5zgwH_~MY-&gokyj2P(+Q(TQ!7t3Z6tu
z`|u}pUh&I{C%=S4wVpK8BQDo5pq_tQU%*=GnMaKa?|&^0(dYfyuEbb8^;chO0ke^CvD=S=gbe+jN
-SEI CERT C++ Coding Standard: DCL20-C. Explicitly specify void when a function accepts no arguments
+SEI CERT C Coding Standard: DCL20-C. Explicitly specify void when a function accepts no arguments
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.s b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.s
deleted file mode 100644
index f4ea6be47056..000000000000
--- a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.s
+++ /dev/null
@@ -1 +0,0 @@
- .file "MistypedFunctionArguments.c"
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qhelp b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qhelp
index 8eb266e3ac3a..20085880b14c 100644
--- a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qhelp
+++ b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qhelp
@@ -30,6 +30,6 @@
-SEI CERT C++ Coding Standard: DCL20-C. Explicitly specify void when a function accepts no arguments
+SEI CERT C Coding Standard: DCL20-C. Explicitly specify void when a function accepts no arguments
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/tests.c b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/tests.c
deleted file mode 100644
index 3c44536ac622..000000000000
--- a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/tests.c
+++ /dev/null
@@ -1,33 +0,0 @@
-//void three_arguments();
-void three_arguments(int x, char y, int *z);
-void pointer_arguments(float *x, void *y, int **z);
-void array_argument(int arr[6]);
-void array_argument2(char arr[6]);
-int var;
-void *pv;
-double d = 3732.70e13L;
-extern unsigned long long *ull;
-
-extern void *a[3];
-
-void calls() {
- three_arguments(*ull, 2, &var); // BAD: arguments 1 and 3 do not match parameters
- three_arguments(&ull, 2, &var); // BAD: arguments 1 and 3 do not match parameters
- three_arguments(&var, 2, &var); // BAD: arguments 1 and 3 do not match parameters
- three_arguments(var, 2, 3.0f); // BAD: arguments 1 and 3 do not match parameters
-
- pointer_arguments(20, 0, 0); // BAD
- pointer_arguments(pv, &var, &pv); // GOOD
- pointer_arguments(&pv, &var, pv); // BAD
- pointer_arguments(&var, a, &pv); // BAD
- pointer_arguments(&var, &pv, a); // BAD
-
- array_argument(&var);
- array_argument(pv);
- array_argument(10);
- array_argument("Hello");
-
- array_argument2("Hello");
-
-}
-
From 59a54df1494a2107250981fefd7fd7fe3794a445 Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Fri, 29 Mar 2019 20:30:40 -0700
Subject: [PATCH 08/27] [CPP-340] cpp/too-many-arguments should remain as
cpp/futile-params.
---
.../src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.ql | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.ql b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.ql
index e58a64caab95..39684fe3acc5 100644
--- a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.ql
+++ b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.ql
@@ -6,7 +6,7 @@
* @kind problem
* @problem.severity warning
* @precision very-high
- * @id cpp/too-many-arguments
+ * @id cpp/futile-params
* @tags correctness
* maintainability
*/
From 8a653b9adc453a70539974b1b869c06547cfd984 Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Fri, 29 Mar 2019 20:34:49 -0700
Subject: [PATCH 09/27] [CPP-340] Fix TooFewArguments.c to actually provide a
()-prototype.
---
.../Likely Bugs/UnderspecifiedFunctions/TooFewArguments.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.c b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.c
index 246d029e5480..93251746fd32 100644
--- a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.c
+++ b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.c
@@ -1,8 +1,9 @@
-
-void one_argument(int x);
+void one_argument();
void calls() {
one_argument(1); // GOOD: `one_argument` will accept and use the argument
one_argument(); // BAD: `one_argument` will receive an undefined value
}
+
+void one_argument(int x);
From 3ec988c39b9caf6b575a60a2bec0dd7db575d3bb Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Mon, 1 Apr 2019 18:39:46 -0700
Subject: [PATCH 10/27] [CPP-340] Rename 'UnspecifiedFunctions' to 'Unspecified
Functions' Make MistypedFunctionArguments.ql more restrictive
(allowing type matching only in the presence of no-op conversions).
---
cpp/config/suites/c/correctness | 4 +-
cpp/config/suites/cpp/correctness | 4 +-
.../MistypedFunctionArguments.c | 7 ++
.../MistypedFunctionArguments.qhelp | 29 +++++
.../MistypedFunctionArguments.ql | 109 ++++++++++++++++++
.../TooFewArguments.c | 9 ++
.../TooFewArguments.qhelp | 35 ++++++
.../TooFewArguments.ql | 31 +++++
.../TooManyArguments.c | 10 ++
.../TooManyArguments.qhelp | 30 +++++
.../TooManyArguments.ql | 29 +++++
.../MistypedFunctionArguments.expected | 11 ++
.../MistypedFunctionArguments.qlref | 1 +
.../TooFewArguments.expected | 4 +
.../TooFewArguments.qlref | 1 +
.../TooManyArguments.expected | 5 +
.../TooManyArguments.qlref | 1 +
.../Underspecified Functions/test.c | 63 ++++++++++
.../Underspecified Functions/test.cpp | 8 ++
19 files changed, 389 insertions(+), 2 deletions(-)
create mode 100644 cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.c
create mode 100644 cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.qhelp
create mode 100644 cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
create mode 100644 cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.c
create mode 100644 cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.qhelp
create mode 100644 cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.ql
create mode 100644 cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.c
create mode 100644 cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.qhelp
create mode 100644 cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
create mode 100644 cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected
create mode 100644 cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.qlref
create mode 100644 cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected
create mode 100644 cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.qlref
create mode 100644 cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected
create mode 100644 cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.qlref
create mode 100644 cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c
create mode 100644 cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.cpp
diff --git a/cpp/config/suites/c/correctness b/cpp/config/suites/c/correctness
index 442e618854d4..b13c4f61752e 100644
--- a/cpp/config/suites/c/correctness
+++ b/cpp/config/suites/c/correctness
@@ -6,6 +6,7 @@
+ semmlecode-cpp-queries/Likely Bugs/Arithmetic/IntMultToLong.ql: /Correctness/Dangerous Conversions
+ semmlecode-cpp-queries/Likely Bugs/Conversion/NonzeroValueCastToPointer.ql: /Correctness/Dangerous Conversions
+ semmlecode-cpp-queries/Likely Bugs/Conversion/ImplicitDowncastFromBitfield.ql: /Correctness/Dangerous Conversions
++ semmlecode-cpp-queries/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql: /Correctness/Dangerous Conversions
+ semmlecode-cpp-queries/Security/CWE/CWE-253/HResultBooleanConversion.ql: /Correctness/Dangerous Conversions
# Consistent Use
+ semmlecode-cpp-queries/Critical/ReturnValueIgnored.ql: /Correctness/Consistent Use
@@ -15,7 +16,8 @@
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/AssignWhereCompareMeant.ql: /Correctness/Common Errors
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/CompareWhereAssignMeant.ql: /Correctness/Common Errors
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/ExprHasNoEffect.ql: /Correctness/Common Errors
-+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/FutileParams.ql: /Correctness/Common Errors
++ semmlecode-cpp-queries/Likely Bugs/Underspecified Functions/TooFewArguments.ql: /Correctness/Common Errors
++ semmlecode-cpp-queries/Likely Bugs/Underspecified Functions/TooManyArguments.ql: /Correctness/Common Errors
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/ShortCircuitBitMask.ql: /Correctness/Common Errors
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/MissingEnumCaseInSwitch.ql: /Correctness/Common Errors
+ semmlecode-cpp-queries/Likely Bugs/Arithmetic/FloatComparison.ql: /Correctness/Common Errors
diff --git a/cpp/config/suites/cpp/correctness b/cpp/config/suites/cpp/correctness
index 00ad7a1ad07d..d1079bdcf608 100644
--- a/cpp/config/suites/cpp/correctness
+++ b/cpp/config/suites/cpp/correctness
@@ -7,6 +7,7 @@
+ semmlecode-cpp-queries/Likely Bugs/Conversion/NonzeroValueCastToPointer.ql: /Correctness/Dangerous Conversions
+ semmlecode-cpp-queries/Likely Bugs/Conversion/ImplicitDowncastFromBitfield.ql: /Correctness/Dangerous Conversions
+ semmlecode-cpp-queries/Likely Bugs/Conversion/CastArrayPointerArithmetic.ql: /Correctness/Dangerous Conversions
++ semmlecode-cpp-queries/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql: /Correctness/Dangerous Conversions
+ semmlecode-cpp-queries/Security/CWE/CWE-253/HResultBooleanConversion.ql: /Correctness/Dangerous Conversions
# Consistent Use
+ semmlecode-cpp-queries/Critical/ReturnValueIgnored.ql: /Correctness/Consistent Use
@@ -16,7 +17,8 @@
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/AssignWhereCompareMeant.ql: /Correctness/Common Errors
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/CompareWhereAssignMeant.ql: /Correctness/Common Errors
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/ExprHasNoEffect.ql: /Correctness/Common Errors
-+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/FutileParams.ql: /Correctness/Common Errors
++ semmlecode-cpp-queries/Likely Bugs/Underspecified Functions/TooFewArguments.ql: /Correctness/Common Errors
++ semmlecode-cpp-queries/Likely Bugs/Underspecified Functions/TooManyArguments.ql: /Correctness/Common Errors
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/ShortCircuitBitMask.ql: /Correctness/Common Errors
+ semmlecode-cpp-queries/Likely Bugs/Likely Typos/MissingEnumCaseInSwitch.ql: /Correctness/Common Errors
+ semmlecode-cpp-queries/Likely Bugs/Arithmetic/FloatComparison.ql: /Correctness/Common Errors
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.c b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.c
new file mode 100644
index 000000000000..fa3235a6e3fe
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.c
@@ -0,0 +1,7 @@
+void three_arguments(int x, int y, int z);
+
+void calls() {
+ int three = 3;
+ three_arguments(1, 2, three); // GOOD
+ three_arguments(1, 2, &three); // BAD
+}
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.qhelp b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.qhelp
new file mode 100644
index 000000000000..6dd3f0eff48d
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.qhelp
@@ -0,0 +1,29 @@
+
+
+
+
+
+A function is called with at least one argument whose type is incompatible with the type of
+ the corresponding parameter of the function being called. This may cause the called function
+ to behave unpredictably.
+
+This may indicate that an incorrect function is being called, or that the
+ signature (parameter list and parameter types) of the called function
+ is not known to the author.
+
+
+
+Call the function with the proper argument types. In some cases, it may
+ suffice to provide an explicit cast of an argument to the desired (parameter) type.
+
+
+
+
+
+
+
+SEI CERT C Coding Standard: DCL20-C. Explicitly specify void when a function accepts no arguments
+
+
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
new file mode 100644
index 000000000000..2ee6826843ec
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
@@ -0,0 +1,109 @@
+/**
+ * @name Call to a function with one or more incompatible arguments
+ * @description A call to a function with at least one argument whose type does
+ * not match the type of the corresponding function parameter. This may indicate
+ * that the author is not familiar with the function being called. Passing mistyped
+ * arguments on a stack may lead to unpredictable function behavior.
+ * @kind problem
+ * @problem.severity warning
+ * @precision very-high
+ * @id cpp/mistyped-function-arguments
+ * @tags correctness
+ * maintainability
+ */
+
+import cpp
+
+pragma[inline]
+int sizeofInt() { result = any(IntType pt).getSize() }
+
+pragma[inline]
+predicate pointerArgTypeMayBeUsed(Type arg, Type parm) {
+ arg = parm
+ or
+ // arithmetic types
+ arg instanceof ArithmeticType and
+ parm instanceof ArithmeticType and
+ arg.getSize() = parm.getSize() and
+ (
+ (
+ arg instanceof IntegralType and
+ parm instanceof IntegralType
+ )
+ or
+ (
+ arg instanceof FloatingPointType and
+ parm instanceof FloatingPointType
+ )
+ )
+ or
+ // pointers to void are ok
+ arg instanceof VoidType
+ or
+ parm instanceof VoidType
+}
+
+pragma[inline]
+predicate argTypeMayBeUsed(Type arg, Type parm) {
+ arg = parm
+ or
+ // float will be promoted to double, and so it should correspond
+ // to the prototype
+ arg instanceof FloatType and parm instanceof DoubleType
+ or
+ // integral types are promoted "up to" (unsigned) int, but not long long.
+ arg instanceof IntegralType and
+ parm instanceof IntegralType and
+ arg.getSize() <= sizeofInt() and
+ parm.getSize() <= sizeofInt()
+ or
+ /*
+ * // we allow interoperability between long long and pointer
+ * arg.getSize() = parm.getSize() and
+ * (
+ * (arg instanceof IntegralType and parm instanceof PointerType)
+ * or
+ * (arg instanceof PointerType and parm instanceof IntegralType)
+ * )
+ * or
+ */
+
+ // pointers to compatible types
+ pointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(),
+ parm.(PointerType).getBaseType().getUnspecifiedType())
+ or
+ pointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(),
+ parm.(ArrayType).getBaseType().getUnspecifiedType())
+ or
+ pointerArgTypeMayBeUsed(arg.(ArrayType).getBaseType().getUnspecifiedType(),
+ parm.(PointerType).getBaseType().getUnspecifiedType())
+ or
+ pointerArgTypeMayBeUsed(arg.(ArrayType).getBaseType().getUnspecifiedType(),
+ parm.(ArrayType).getBaseType().getUnspecifiedType())
+}
+
+// This predicate doesn't necessarily have to exist, but if it does exist
+// then it must be inline to make sure we don't enumerate all pairs of
+// compatible types.
+// Its body could also just be hand-inlined where it's used.
+pragma[inline]
+predicate argMayBeUsed(Expr arg, Parameter parm) {
+ argTypeMayBeUsed(arg.getFullyConverted().getType().getUnspecifiedType(),
+ parm.getType().getUnspecifiedType())
+}
+
+from FunctionCall fc, Function f, Parameter p
+where
+ f = fc.getTarget() and
+ p = f.getAParameter() and
+ not f.isVarargs() and
+ p.getIndex() < fc.getNumberOfArguments() and
+ // There must be a zero-parameter declaration
+ exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
+ fde.getNumberOfParameters() = 0
+ ) and
+ // Parameter p and its corresponding call argument must have mismatched types
+ not argMayBeUsed(fc.getArgument(p.getIndex()), p)
+select fc, "Calling $@: argument $@ of type $@ is incompatible with parameter $@.", f, f.toString(),
+ fc.getArgument(p.getIndex()) as arg, arg.toString(), arg.getFullyConverted().getType() as type,
+ type.toString(), p, p.getTypedName()
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.c b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.c
new file mode 100644
index 000000000000..93251746fd32
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.c
@@ -0,0 +1,9 @@
+void one_argument();
+
+void calls() {
+ one_argument(1); // GOOD: `one_argument` will accept and use the argument
+
+ one_argument(); // BAD: `one_argument` will receive an undefined value
+}
+
+void one_argument(int x);
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.qhelp b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.qhelp
new file mode 100644
index 000000000000..20085880b14c
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.qhelp
@@ -0,0 +1,35 @@
+
+
+
+
+
+A function is called with fewer arguments than there are parameters of the function.
+
+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.
+
+In C, function calls generally need to provide the same number of arguments as there are
+ arguments to the function. (Variadic functions can accept additional arguments.) Providing
+ fewer arguments than there are parameters is extremely dangerous, as the called function
+ will nevertheless try to obtain the missing arguments' values, either from the stack
+ or from machine registers. As a result, the function may behave unpredictably.
+
+If the called function modifies a parameter corresponding to a missing argument, it
+ may alter the state of the program upon its return. An attacker could use this to,
+ for example, alter the control flow of the program to access forbidden resources.
+
+
+
+Call the function with the correct number of arguments.
+
+
+
+
+
+
+
+SEI CERT C Coding Standard: DCL20-C. Explicitly specify void when a function accepts no arguments
+
+
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.ql
new file mode 100644
index 000000000000..575428a2fbe0
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.ql
@@ -0,0 +1,31 @@
+/**
+ * @name Call to function with fewer arguments than declared parameters
+ * @description A function call passed fewer arguments than the number of
+ * declared parameters of the function. This may indicate
+ * that the code does not follow the author's intent. It is also a vulnerability,
+ * since the function is like to operate on undefined data.
+ * @kind problem
+ * @problem.severity error
+ * @precision very-high
+ * @id cpp/too-few-params
+ * @tags correctness
+ * maintainability
+ * security
+ */
+
+import cpp
+
+from FunctionCall fc, Function f
+where
+ f = fc.getTarget() and
+ not f.isVarargs() and
+ // There must be a zero-parameter declaration (explicit or implicit)
+ exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
+ fde.getNumberOfParameters() = 0
+ ) and
+ // There is an explicit declaration of the function whose parameter count is larger
+ // than the number of call arguments
+ exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
+ not fde.isImplicit() and fde.getNumberOfParameters() > fc.getNumberOfArguments()
+ )
+select fc, "This call has fewer arguments than required by $@.", f, f.toString()
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.c b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.c
new file mode 100644
index 000000000000..fa35f028706d
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.c
@@ -0,0 +1,10 @@
+void one_argument();
+
+void calls() {
+
+ one_argument(1); // GOOD: `one_argument` will accept and use the argument
+
+ one_argument(1, 2); // BAD: `one_argument` will use the first argument but ignore the second
+}
+
+void one_argument(int x);
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.qhelp b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.qhelp
new file mode 100644
index 000000000000..43200aa0ae91
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.qhelp
@@ -0,0 +1,30 @@
+
+
+
+
+
+A function is called with more arguments than there are parameters of the function.
+
+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.
+
+In C, function calls generally need to provide the same number of arguments as there are
+ arguments to the function. (Variadic functions can accept additional arguments.) Providing
+ more arguments than there are parameters incurs an unneeded computational overhead, both
+ in terms of time and of additional stack space.
+
+
+
+Call the function with the correct number of arguments.
+
+
+
+
+
+
+
+SEI CERT C Coding Standard: DCL20-C. Explicitly specify void when a function accepts no arguments
+
+
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
new file mode 100644
index 000000000000..39684fe3acc5
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
@@ -0,0 +1,29 @@
+/**
+ * @name Call to function with extraneous parameters
+ * @description A function call to a function passed more arguments than there are
+ * declared parameters of the function. This may indicate
+ * that the code does not follow the author's intent.
+ * @kind problem
+ * @problem.severity warning
+ * @precision very-high
+ * @id cpp/futile-params
+ * @tags correctness
+ * maintainability
+ */
+
+import cpp
+
+from FunctionCall fc, Function f
+where
+ f = fc.getTarget() and
+ not f.isVarargs() and
+ // There must be a zero-parameter declaration (explicit or implicit)
+ exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
+ fde.getNumberOfParameters() = 0
+ ) and
+ // There must not exist a declaration with the number of parameters
+ // at least as large as the number of call arguments
+ not exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
+ fde.getNumberOfParameters() >= fc.getNumberOfArguments()
+ )
+select fc, "This call has more arguments than required by $@.", f, f.toString()
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected
new file mode 100644
index 000000000000..508d80b7ed3c
--- /dev/null
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected
@@ -0,0 +1,11 @@
+| test.c:25:3:25:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:24:3:24:3 | not_yet_declared2 | not_yet_declared2 | test.c:25:21:25:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:45:24:45:26 | p#0 | int p#0 |
+| test.c:25:3:25:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:45:6:45:22 | not_yet_declared2 | not_yet_declared2 | test.c:25:21:25:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:45:24:45:26 | p#0 | int p#0 |
+| test.c:32:3:32:29 | call to declared_empty_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:46:6:46:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:32:31:32:32 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:46:38:46:38 | x | int x |
+| test.c:36:3:36:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:49:6:49:30 | not_declared_defined_with | not_declared_defined_with | test.c:36:29:36:31 | 4 | 4 | file://:0:0:0:0 | long long | long long | test.c:49:36:49:36 | x | int x |
+| test.c:36:3:36:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:49:6:49:30 | not_declared_defined_with | not_declared_defined_with | test.c:36:37:36:42 | 2500000000.0 | 2500000000.0 | file://:0:0:0:0 | double | double | test.c:49:50:49:50 | z | int z |
+| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:39:26:39:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:61:34:61:34 | x | int * x |
+| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:39:34:39:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:61:43:61:43 | y | void * y |
+| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:61:6:61:27 | declared_with_pointers | declared_with_pointers | test.c:39:26:39:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:61:34:61:34 | x | int * x |
+| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:61:6:61:27 | declared_with_pointers | declared_with_pointers | test.c:39:34:39:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:61:43:61:43 | y | void * y |
+| test.c:41:3:41:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:6:6:6:24 | declared_with_array | declared_with_array | test.c:41:23:41:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:62:31:62:31 | a | char[6] a |
+| test.c:41:3:41:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:62:6:62:24 | declared_with_array | declared_with_array | test.c:41:23:41:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:62:31:62:31 | a | char[6] a |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.qlref b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.qlref
new file mode 100644
index 000000000000..e61361d6bfee
--- /dev/null
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.qlref
@@ -0,0 +1 @@
+Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected
new file mode 100644
index 000000000000..6b56644df7ca
--- /dev/null
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected
@@ -0,0 +1,4 @@
+| test.c:26:3:26:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:24:3:24:3 | not_yet_declared2 | not_yet_declared2 |
+| test.c:26:3:26:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:45:6:45:22 | not_yet_declared2 | not_yet_declared2 |
+| test.c:28:3:28:29 | call to declared_empty_defined_with | This call has fewer arguments than required by $@. | test.c:46:6:46:32 | declared_empty_defined_with | declared_empty_defined_with |
+| test.c:56:10:56:20 | call to dereference | This call has fewer arguments than required by $@. | test.c:59:5:59:15 | dereference | dereference |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.qlref b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.qlref
new file mode 100644
index 000000000000..710092c54d85
--- /dev/null
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.qlref
@@ -0,0 +1 @@
+Likely Bugs/Underspecified Functions/TooFewArguments.ql
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected
new file mode 100644
index 000000000000..89ae7d04771e
--- /dev/null
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected
@@ -0,0 +1,5 @@
+| test.c:16:3:16:16 | call to declared_empty | This call has more arguments than required by $@. | test.c:1:6:1:19 | declared_empty | declared_empty |
+| test.c:21:3:21:12 | call to undeclared | This call has more arguments than required by $@. | test.c:20:3:20:3 | undeclared | undeclared |
+| test.c:23:3:23:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:23:3:23:3 | not_yet_declared1 | not_yet_declared1 |
+| test.c:23:3:23:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:44:6:44:22 | not_yet_declared1 | not_yet_declared1 |
+| test.c:33:3:33:29 | call to declared_empty_defined_with | This call has more arguments than required by $@. | test.c:46:6:46:32 | declared_empty_defined_with | declared_empty_defined_with |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.qlref b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.qlref
new file mode 100644
index 000000000000..ca44af39c2bf
--- /dev/null
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.qlref
@@ -0,0 +1 @@
+Likely Bugs/Underspecified Functions/TooManyArguments.ql
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c
new file mode 100644
index 000000000000..9763d3936afe
--- /dev/null
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c
@@ -0,0 +1,63 @@
+void declared_empty();
+void declared_void(void);
+void declared_with(int);
+void declared_empty_defined_with();
+void declared_with_pointers();
+void declared_with_array();
+
+struct _s { int a, b; } s;
+
+int ca[4] = { 1, 2, 3, 4 };
+
+void *pv;
+
+void test() {
+ declared_empty(); // GOOD
+ declared_empty(1); // BAD
+ declared_void(); // GOOD
+ declared_with(1); // GOOD
+
+ undeclared(); // GOOD
+ undeclared(1); // BAD
+
+ not_yet_declared1(1); // BAD
+ not_yet_declared2(1); // GOOD
+ not_yet_declared2(ca); // BAD
+ not_yet_declared2(); // BAD
+
+ declared_empty_defined_with(); // BAD
+ declared_empty_defined_with(1); // GOOD
+
+ int x;
+ declared_empty_defined_with(&x); // BAD
+ declared_empty_defined_with(3, &x); // BAD
+
+ not_declared_defined_with(-1, 0, 2U); // GOOD
+ not_declared_defined_with(4LL, 0, 2.5e9f); // BAD
+
+ declared_with_pointers(pv, ca); // GOOD
+ declared_with_pointers(3.5e15, 0); // BAD
+ declared_with_array("Hello"); // GOOD
+ declared_with_array(&x); // BAD
+}
+
+void not_yet_declared1();
+void not_yet_declared2(int);
+void declared_empty_defined_with(int x) {
+ // do nothing
+}
+void not_declared_defined_with(int x, int y, int z) {
+ return;
+}
+
+int dereference();
+
+int caller(void) {
+ return dereference(); // BAD
+}
+
+int dereference(int *x) { return *x; }
+
+void declared_with_pointers(int *x, void *y);
+void declared_with_array(char a [6]);
+
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.cpp b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.cpp
new file mode 100644
index 000000000000..855fdaea3fd3
--- /dev/null
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.cpp
@@ -0,0 +1,8 @@
+void cpp_varargs(...);
+void bar();
+
+void test() {
+ cpp_varargs(); // GOOD
+ cpp_varargs(1); // GOOD
+ __builtin_constant_p("something"); // GOOD: builtin
+}
\ No newline at end of file
From bd139829ea912c9736b9173f6a515176524657bb Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Mon, 1 Apr 2019 18:44:49 -0700
Subject: [PATCH 11/27] [CPP-340] Delete old 'UnspecifiedFunctions' folders
---
.../MistypedFunctionArguments.c | 7 --
.../MistypedFunctionArguments.qhelp | 29 -------
.../MistypedFunctionArguments.ql | 82 -------------------
.../UnderspecifiedFunctions/TooFewArguments.c | 9 --
.../TooFewArguments.qhelp | 35 --------
.../TooFewArguments.ql | 31 -------
.../TooManyArguments.c | 10 ---
.../TooManyArguments.qhelp | 30 -------
.../TooManyArguments.ql | 29 -------
.../MistypedFunctionArguments.expected | 7 --
.../MistypedFunctionArguments.qlref | 1 -
.../TooFewArguments.expected | 4 -
.../TooFewArguments.qlref | 1 -
.../TooManyArguments.expected | 5 --
.../TooManyArguments.qlref | 1 -
.../UnderspecifiedFunctions/test.c | 63 --------------
.../UnderspecifiedFunctions/test.cpp | 8 --
17 files changed, 352 deletions(-)
delete mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.c
delete mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.qhelp
delete mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.ql
delete mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.c
delete mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qhelp
delete mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.ql
delete mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.c
delete mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.qhelp
delete mode 100644 cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.ql
delete mode 100644 cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.expected
delete mode 100644 cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.qlref
delete mode 100644 cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.expected
delete mode 100644 cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qlref
delete mode 100644 cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.expected
delete mode 100644 cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.qlref
delete mode 100644 cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/test.c
delete mode 100644 cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/test.cpp
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.c b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.c
deleted file mode 100644
index fa3235a6e3fe..000000000000
--- a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.c
+++ /dev/null
@@ -1,7 +0,0 @@
-void three_arguments(int x, int y, int z);
-
-void calls() {
- int three = 3;
- three_arguments(1, 2, three); // GOOD
- three_arguments(1, 2, &three); // BAD
-}
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.qhelp b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.qhelp
deleted file mode 100644
index 6dd3f0eff48d..000000000000
--- a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.qhelp
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-A function is called with at least one argument whose type is incompatible with the type of
- the corresponding parameter of the function being called. This may cause the called function
- to behave unpredictably.
-
-This may indicate that an incorrect function is being called, or that the
- signature (parameter list and parameter types) of the called function
- is not known to the author.
-
-
-
-Call the function with the proper argument types. In some cases, it may
- suffice to provide an explicit cast of an argument to the desired (parameter) type.
-
-
-
-
-
-
-
-SEI CERT C Coding Standard: DCL20-C. Explicitly specify void when a function accepts no arguments
-
-
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.ql b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.ql
deleted file mode 100644
index 17f60ccba976..000000000000
--- a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.ql
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * @name Call to a function with one or more incompatible arguments
- * @description A call to a function with at least one argument whose type does
- * not match the type of the corresponding function parameter. This may indicate
- * that the author is not familiar with the function being called. Passing mistyped
- * arguments on a stack may lead to unpredictable function behavior.
- * @kind problem
- * @problem.severity warning
- * @precision very-high
- * @id cpp/mistyped-function-arguments
- * @tags correctness
- * maintainability
- */
-
-import cpp
-
-pragma[inline]
-predicate argTypeMayBeImplicitlyConverted(Type arg, Type parm) {
- arg = parm
- or
- // integral and floating-point types are implicitly convertible in C
- arg instanceof ArithmeticType and parm instanceof ArithmeticType
- or
- // integral values may be used to initialize pointers (but NOT array addresses)
- arg instanceof IntegralType and parm instanceof PointerType
- or
- // pointers-to-void may be used for arbitrary pointers
- arg instanceof VoidPointerType and parm instanceof PointerType
- or
- arg instanceof PointerType and parm instanceof VoidPointerType
- or
- arg instanceof ArrayType and parm instanceof VoidPointerType
- or
- arg instanceof VoidPointerType and parm instanceof ArrayType
- or
- // pointers to same types
- arg.(PointerType).getBaseType().getUnspecifiedType() = parm
- .(PointerType)
- .getBaseType()
- .getUnspecifiedType()
- or
- arg.(ArrayType).getBaseType().getUnspecifiedType() = parm
- .(PointerType)
- .getBaseType()
- .getUnspecifiedType()
- or
- arg.(PointerType).getBaseType().getUnspecifiedType() = parm
- .(ArrayType)
- .getBaseType()
- .getUnspecifiedType()
- or
- arg.(ArrayType).getBaseType().getUnspecifiedType() = parm
- .(ArrayType)
- .getBaseType()
- .getUnspecifiedType()
-}
-
-// This predicate doesn't necessarily have to exist, but if it does exist
-// then it must be inline to make sure we don't enumerate all pairs of
-// compatible types.
-// Its body could also just be hand-inlined where it's used.
-pragma[inline]
-predicate argMayBeImplicitlyConverted(Expr arg, Parameter parm) {
- argTypeMayBeImplicitlyConverted(arg.getFullyConverted().getType().getUnspecifiedType(),
- parm.getType().getUnspecifiedType())
-}
-
-from FunctionCall fc, Function f, Parameter p
-where
- f = fc.getTarget() and
- p = f.getAParameter() and
- not f.isVarargs() and
- p.getIndex() < fc.getNumberOfArguments() and
- // There must be a zero-parameter declaration
- exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
- fde.getNumberOfParameters() = 0
- ) and
- // Parameter p and its corresponding call argument must have mismatched types
- not argMayBeImplicitlyConverted(fc.getArgument(p.getIndex()), p)
-select fc, "Calling $@: argument $@ of type $@ is incompatible with parameter $@.", f, f.toString(),
- fc.getArgument(p.getIndex()) as arg, arg.toString(), arg.getFullyConverted().getType() as type,
- type.toString(), p, p.getTypedName()
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.c b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.c
deleted file mode 100644
index 93251746fd32..000000000000
--- a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.c
+++ /dev/null
@@ -1,9 +0,0 @@
-void one_argument();
-
-void calls() {
- one_argument(1); // GOOD: `one_argument` will accept and use the argument
-
- one_argument(); // BAD: `one_argument` will receive an undefined value
-}
-
-void one_argument(int x);
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qhelp b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qhelp
deleted file mode 100644
index 20085880b14c..000000000000
--- a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qhelp
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-A function is called with fewer arguments than there are parameters of the function.
-
-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.
-
-In C, function calls generally need to provide the same number of arguments as there are
- arguments to the function. (Variadic functions can accept additional arguments.) Providing
- fewer arguments than there are parameters is extremely dangerous, as the called function
- will nevertheless try to obtain the missing arguments' values, either from the stack
- or from machine registers. As a result, the function may behave unpredictably.
-
-If the called function modifies a parameter corresponding to a missing argument, it
- may alter the state of the program upon its return. An attacker could use this to,
- for example, alter the control flow of the program to access forbidden resources.
-
-
-
-Call the function with the correct number of arguments.
-
-
-
-
-
-
-
-SEI CERT C Coding Standard: DCL20-C. Explicitly specify void when a function accepts no arguments
-
-
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.ql b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.ql
deleted file mode 100644
index 8d031eed0da0..000000000000
--- a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.ql
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * @name Call to function with fewer arguments than declared parameters
- * @description A function call passed fewer arguments than the number of
- * declared parameters of the function. This may indicate
- * that the code does not follow the author's intent. It is also a vulnerability,
- * since the function is like to operate on undefined data.
- * @kind problem
- * @problem.severity error
- * @precision very-high
- * @id cpp/futile-params
- * @tags correctness
- * maintainability
- * security
- */
-
-import cpp
-
-from FunctionCall fc, Function f
-where
- f = fc.getTarget() and
- not f.isVarargs() and
- // There must be a zero-parameter declaration (explicit or implicit)
- exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
- fde.getNumberOfParameters() = 0
- ) and
- // There is an explicit declaration of the function whose parameter count is larger
- // than the number of call arguments
- exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
- not fde.isImplicit() and fde.getNumberOfParameters() > fc.getNumberOfArguments()
- )
-select fc, "This call has fewer arguments than required by $@.", f, f.toString()
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.c b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.c
deleted file mode 100644
index fa35f028706d..000000000000
--- a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.c
+++ /dev/null
@@ -1,10 +0,0 @@
-void one_argument();
-
-void calls() {
-
- one_argument(1); // GOOD: `one_argument` will accept and use the argument
-
- one_argument(1, 2); // BAD: `one_argument` will use the first argument but ignore the second
-}
-
-void one_argument(int x);
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.qhelp b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.qhelp
deleted file mode 100644
index 43200aa0ae91..000000000000
--- a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.qhelp
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-A function is called with more arguments than there are parameters of the function.
-
-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.
-
-In C, function calls generally need to provide the same number of arguments as there are
- arguments to the function. (Variadic functions can accept additional arguments.) Providing
- more arguments than there are parameters incurs an unneeded computational overhead, both
- in terms of time and of additional stack space.
-
-
-
-Call the function with the correct number of arguments.
-
-
-
-
-
-
-
-SEI CERT C Coding Standard: DCL20-C. Explicitly specify void when a function accepts no arguments
-
-
diff --git a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.ql b/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.ql
deleted file mode 100644
index 39684fe3acc5..000000000000
--- a/cpp/ql/src/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.ql
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * @name Call to function with extraneous parameters
- * @description A function call to a function passed more arguments than there are
- * declared parameters of the function. This may indicate
- * that the code does not follow the author's intent.
- * @kind problem
- * @problem.severity warning
- * @precision very-high
- * @id cpp/futile-params
- * @tags correctness
- * maintainability
- */
-
-import cpp
-
-from FunctionCall fc, Function f
-where
- f = fc.getTarget() and
- not f.isVarargs() and
- // There must be a zero-parameter declaration (explicit or implicit)
- exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
- fde.getNumberOfParameters() = 0
- ) and
- // There must not exist a declaration with the number of parameters
- // at least as large as the number of call arguments
- not exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
- fde.getNumberOfParameters() >= fc.getNumberOfArguments()
- )
-select fc, "This call has more arguments than required by $@.", f, f.toString()
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.expected
deleted file mode 100644
index a8ce8fe0506c..000000000000
--- a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.expected
+++ /dev/null
@@ -1,7 +0,0 @@
-| test.c:25:3:25:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:24:3:24:3 | not_yet_declared2 | not_yet_declared2 | test.c:25:21:25:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:45:24:45:26 | p#0 | int p#0 |
-| test.c:25:3:25:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:45:6:45:22 | not_yet_declared2 | not_yet_declared2 | test.c:25:21:25:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:45:24:45:26 | p#0 | int p#0 |
-| test.c:32:3:32:29 | call to declared_empty_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:46:6:46:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:32:31:32:32 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:46:38:46:38 | x | int x |
-| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:39:26:39:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:61:34:61:34 | x | int * x |
-| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:61:6:61:27 | declared_with_pointers | declared_with_pointers | test.c:39:26:39:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:61:34:61:34 | x | int * x |
-| test.c:41:3:41:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:6:6:6:24 | declared_with_array | declared_with_array | test.c:41:23:41:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:62:31:62:31 | a | char[6] a |
-| test.c:41:3:41:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:62:6:62:24 | declared_with_array | declared_with_array | test.c:41:23:41:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:62:31:62:31 | a | char[6] a |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.qlref b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.qlref
deleted file mode 100644
index e2e24d78bc38..000000000000
--- a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.qlref
+++ /dev/null
@@ -1 +0,0 @@
-Likely Bugs/UnderspecifiedFunctions/MistypedFunctionArguments.ql
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.expected
deleted file mode 100644
index 6b56644df7ca..000000000000
--- a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.expected
+++ /dev/null
@@ -1,4 +0,0 @@
-| test.c:26:3:26:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:24:3:24:3 | not_yet_declared2 | not_yet_declared2 |
-| test.c:26:3:26:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:45:6:45:22 | not_yet_declared2 | not_yet_declared2 |
-| test.c:28:3:28:29 | call to declared_empty_defined_with | This call has fewer arguments than required by $@. | test.c:46:6:46:32 | declared_empty_defined_with | declared_empty_defined_with |
-| test.c:56:10:56:20 | call to dereference | This call has fewer arguments than required by $@. | test.c:59:5:59:15 | dereference | dereference |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qlref b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qlref
deleted file mode 100644
index cfc3bd165a23..000000000000
--- a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooFewArguments.qlref
+++ /dev/null
@@ -1 +0,0 @@
-Likely Bugs/UnderspecifiedFunctions/TooFewArguments.ql
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.expected
deleted file mode 100644
index 89ae7d04771e..000000000000
--- a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.expected
+++ /dev/null
@@ -1,5 +0,0 @@
-| test.c:16:3:16:16 | call to declared_empty | This call has more arguments than required by $@. | test.c:1:6:1:19 | declared_empty | declared_empty |
-| test.c:21:3:21:12 | call to undeclared | This call has more arguments than required by $@. | test.c:20:3:20:3 | undeclared | undeclared |
-| test.c:23:3:23:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:23:3:23:3 | not_yet_declared1 | not_yet_declared1 |
-| test.c:23:3:23:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:44:6:44:22 | not_yet_declared1 | not_yet_declared1 |
-| test.c:33:3:33:29 | call to declared_empty_defined_with | This call has more arguments than required by $@. | test.c:46:6:46:32 | declared_empty_defined_with | declared_empty_defined_with |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.qlref b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.qlref
deleted file mode 100644
index 9438d5ad537b..000000000000
--- a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/TooManyArguments.qlref
+++ /dev/null
@@ -1 +0,0 @@
-Likely Bugs/UnderspecifiedFunctions/TooManyArguments.ql
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/test.c b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/test.c
deleted file mode 100644
index 16f10479f66c..000000000000
--- a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/test.c
+++ /dev/null
@@ -1,63 +0,0 @@
-void declared_empty();
-void declared_void(void);
-void declared_with(int);
-void declared_empty_defined_with();
-void declared_with_pointers();
-void declared_with_array();
-
-struct _s { int a, b; } s;
-
-int ca[4] = { 1, 2, 3, 4 };
-
-void *pv;
-
-void test() {
- declared_empty(); // GOOD
- declared_empty(1); // BAD
- declared_void(); // GOOD
- declared_with(1); // GOOD
-
- undeclared(); // GOOD
- undeclared(1); // BAD
-
- not_yet_declared1(1); // BAD
- not_yet_declared2(1); // GOOD
- not_yet_declared2(ca); // BAD
- not_yet_declared2(); // BAD
-
- declared_empty_defined_with(); // BAD
- declared_empty_defined_with(1); // GOOD
-
- int x;
- declared_empty_defined_with(&x); // BAD
- declared_empty_defined_with(3.0f, &x); // BAD
-
- not_declared_defined_with(1.0, 0, 2U); // GOOD
- not_declared_defined_with(4LL, 0, 2.5e9); // GOOD
-
- declared_with_pointers(pv, ca); // GOOD
- declared_with_pointers(3.5e15, 0); // BAD
- declared_with_array("Hello"); // GOOD
- declared_with_array(&x); // BAD
-}
-
-void not_yet_declared1();
-void not_yet_declared2(int);
-void declared_empty_defined_with(int x) {
- // do nothing
-}
-void not_declared_defined_with(int x, int y, int z) {
- return;
-}
-
-int dereference();
-
-int caller(void) {
- return dereference(); // BAD
-}
-
-int dereference(int *x) { return *x; }
-
-void declared_with_pointers(int *x, void *y);
-void declared_with_array(char a [6]);
-
diff --git a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/test.cpp b/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/test.cpp
deleted file mode 100644
index 855fdaea3fd3..000000000000
--- a/cpp/ql/test/query-tests/Likely Bugs/UnderspecifiedFunctions/test.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-void cpp_varargs(...);
-void bar();
-
-void test() {
- cpp_varargs(); // GOOD
- cpp_varargs(1); // GOOD
- __builtin_constant_p("something"); // GOOD: builtin
-}
\ No newline at end of file
From 96b8bdfeb57f6ffd2a1a847017e4b64382703d5a Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Mon, 1 Apr 2019 19:15:27 -0700
Subject: [PATCH 12/27] [CPP-340] Add new queries to analysis-cpp.md; correct
id of TooFewArguments.ql
---
change-notes/1.21/analysis-cpp.md | 3 +++
.../Likely Bugs/Underspecified Functions/TooFewArguments.ql | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/change-notes/1.21/analysis-cpp.md b/change-notes/1.21/analysis-cpp.md
index 733a8eb9531f..f0f2d5a83394 100644
--- a/change-notes/1.21/analysis-cpp.md
+++ b/change-notes/1.21/analysis-cpp.md
@@ -6,6 +6,8 @@
| **Query** | **Tags** | **Purpose** |
|-----------------------------|-----------|--------------------------------------------------------------------|
+| `()`-declared function called with too few arguments (`cpp/too-few-arguments`) | Correctness | Find all cases where the number of arguments is less than the number of parameters of the function, provided the function is also properly declared/defined elsewhere. |
+| `()`-declared function called with mismatched arguments (`cpp/mismatched-function-arguments`) | Correctness | Find all cases where the types of arguments do not match the types of parameters of the function, provided the function is also properly declared/defined elsewhere. |
## Changes to existing queries
@@ -18,5 +20,6 @@
| Resource not released in destructor (`cpp/resource-not-released-in-destructor`) | Fewer false positive results | Resource allocation and deallocation functions are now determined more accurately. |
| Comparison result is always the same | Fewer false positive results | The range analysis library is now more conservative about floating point values being possibly `NaN` |
| Wrong type of arguments to formatting function (`cpp/wrong-type-format-argument`) | More correct results and fewer false positive results | This query now more accurately identifies wide and non-wide string/character format arguments on different platforms. Platform detection has also been made more accurate for the purposes of this query. |
+| `()`-declared function called with too many arguments (`cpp/futile-params`) | Improved coverage | Query has been generalized to find all cases where the number of arguments exceedes the number of parameters of the function, provided the function is also properly declared/defined elsewhere. |
## Changes to QL libraries
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.ql
index 575428a2fbe0..2a7b9a0e7ab0 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.ql
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.ql
@@ -7,7 +7,7 @@
* @kind problem
* @problem.severity error
* @precision very-high
- * @id cpp/too-few-params
+ * @id cpp/too-few-arguments
* @tags correctness
* maintainability
* security
From e4ce8347bc14cd53aabe162f4402cd2d19306ffd Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Wed, 3 Apr 2019 16:19:37 -0700
Subject: [PATCH 13/27] [CPP-340] Simplify MistypedFunctionArguments.ql and
reduce its precision from very-high to high.
---
.../MistypedFunctionArguments.ql | 32 ++-----------------
1 file changed, 3 insertions(+), 29 deletions(-)
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
index 2ee6826843ec..f8870434ef77 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
@@ -6,7 +6,7 @@
* arguments on a stack may lead to unpredictable function behavior.
* @kind problem
* @problem.severity warning
- * @precision very-high
+ * @precision high
* @id cpp/mistyped-function-arguments
* @tags correctness
* maintainability
@@ -14,9 +14,6 @@
import cpp
-pragma[inline]
-int sizeofInt() { result = any(IntType pt).getSize() }
-
pragma[inline]
predicate pointerArgTypeMayBeUsed(Type arg, Type parm) {
arg = parm
@@ -47,39 +44,16 @@ pragma[inline]
predicate argTypeMayBeUsed(Type arg, Type parm) {
arg = parm
or
- // float will be promoted to double, and so it should correspond
- // to the prototype
- arg instanceof FloatType and parm instanceof DoubleType
- or
- // integral types are promoted "up to" (unsigned) int, but not long long.
+ // we treat signed and unsigned versions of integer types as compatible.
arg instanceof IntegralType and
- parm instanceof IntegralType and
- arg.getSize() <= sizeofInt() and
- parm.getSize() <= sizeofInt()
+ parm instanceof IntegralType
or
- /*
- * // we allow interoperability between long long and pointer
- * arg.getSize() = parm.getSize() and
- * (
- * (arg instanceof IntegralType and parm instanceof PointerType)
- * or
- * (arg instanceof PointerType and parm instanceof IntegralType)
- * )
- * or
- */
-
// pointers to compatible types
pointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(),
parm.(PointerType).getBaseType().getUnspecifiedType())
or
pointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(),
parm.(ArrayType).getBaseType().getUnspecifiedType())
- or
- pointerArgTypeMayBeUsed(arg.(ArrayType).getBaseType().getUnspecifiedType(),
- parm.(PointerType).getBaseType().getUnspecifiedType())
- or
- pointerArgTypeMayBeUsed(arg.(ArrayType).getBaseType().getUnspecifiedType(),
- parm.(ArrayType).getBaseType().getUnspecifiedType())
}
// This predicate doesn't necessarily have to exist, but if it does exist
From ef54b012e0f80d1f9cbf89df069d89c61dda5578 Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Fri, 5 Apr 2019 15:43:38 -0700
Subject: [PATCH 14/27] [CPP-340] Fixed .expected file to match new query.
---
.../Underspecified Functions/MistypedFunctionArguments.expected | 1 -
1 file changed, 1 deletion(-)
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected
index 508d80b7ed3c..a9661b060773 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected
@@ -1,7 +1,6 @@
| test.c:25:3:25:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:24:3:24:3 | not_yet_declared2 | not_yet_declared2 | test.c:25:21:25:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:45:24:45:26 | p#0 | int p#0 |
| test.c:25:3:25:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:45:6:45:22 | not_yet_declared2 | not_yet_declared2 | test.c:25:21:25:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:45:24:45:26 | p#0 | int p#0 |
| test.c:32:3:32:29 | call to declared_empty_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:46:6:46:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:32:31:32:32 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:46:38:46:38 | x | int x |
-| test.c:36:3:36:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:49:6:49:30 | not_declared_defined_with | not_declared_defined_with | test.c:36:29:36:31 | 4 | 4 | file://:0:0:0:0 | long long | long long | test.c:49:36:49:36 | x | int x |
| test.c:36:3:36:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:49:6:49:30 | not_declared_defined_with | not_declared_defined_with | test.c:36:37:36:42 | 2500000000.0 | 2500000000.0 | file://:0:0:0:0 | double | double | test.c:49:50:49:50 | z | int z |
| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:39:26:39:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:61:34:61:34 | x | int * x |
| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:39:34:39:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:61:43:61:43 | y | void * y |
From dc7497835e20d12c368d5bb3b6c08b4cc57d7607 Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Wed, 10 Apr 2019 09:55:37 -0700
Subject: [PATCH 15/27] [CPP-340] Make the query more strict (again).
---
.../MistypedFunctionArguments.ql | 51 +++++++++++--------
.../MistypedFunctionArguments.expected | 26 ++++++----
.../TooFewArguments.expected | 6 +--
.../TooManyArguments.expected | 4 +-
.../Underspecified Functions/test.c | 21 ++++++++
5 files changed, 72 insertions(+), 36 deletions(-)
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
index f8870434ef77..972b7f7c71d7 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
@@ -23,15 +23,11 @@ predicate pointerArgTypeMayBeUsed(Type arg, Type parm) {
parm instanceof ArithmeticType and
arg.getSize() = parm.getSize() and
(
- (
- arg instanceof IntegralType and
- parm instanceof IntegralType
- )
+ arg instanceof IntegralType and
+ parm instanceof IntegralType
or
- (
- arg instanceof FloatingPointType and
- parm instanceof FloatingPointType
- )
+ arg instanceof FloatingPointType and
+ parm instanceof FloatingPointType
)
or
// pointers to void are ok
@@ -44,16 +40,23 @@ pragma[inline]
predicate argTypeMayBeUsed(Type arg, Type parm) {
arg = parm
or
- // we treat signed and unsigned versions of integer types as compatible.
+ // float arguments will have been promoted to double,
+ // and the parameter must match this
+ arg instanceof DoubleType and
+ parm instanceof DoubleType
+ or
+ // integral arguments are promoted to int (but not long long).
arg instanceof IntegralType and
- parm instanceof IntegralType
+ arg.getSize() = 4 and
+ parm instanceof IntegralType and
+ parm.getSize() = 4
or
// pointers to compatible types
pointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(),
- parm.(PointerType).getBaseType().getUnspecifiedType())
+ parm.(PointerType).getBaseType().getUnderlyingType().getUnspecifiedType())
or
pointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(),
- parm.(ArrayType).getBaseType().getUnspecifiedType())
+ parm.(ArrayType).getBaseType().getUnderlyingType().getUnspecifiedType())
}
// This predicate doesn't necessarily have to exist, but if it does exist
@@ -62,8 +65,16 @@ predicate argTypeMayBeUsed(Type arg, Type parm) {
// Its body could also just be hand-inlined where it's used.
pragma[inline]
predicate argMayBeUsed(Expr arg, Parameter parm) {
- argTypeMayBeUsed(arg.getFullyConverted().getType().getUnspecifiedType(),
- parm.getType().getUnspecifiedType())
+ argTypeMayBeUsed(arg.getFullyConverted().getType().getUnderlyingType().getUnspecifiedType(),
+ parm.getType().getUnderlyingType().getUnspecifiedType())
+}
+
+// True if function was ()-declared, but not (void)-declared
+pragma[inline]
+predicate hasZeroParamDecl(Function f) {
+ exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
+ not fde.hasVoidParamList() and fde.getNumberOfParameters() = 0
+ )
}
from FunctionCall fc, Function f, Parameter p
@@ -72,12 +83,10 @@ where
p = f.getAParameter() and
not f.isVarargs() and
p.getIndex() < fc.getNumberOfArguments() and
- // There must be a zero-parameter declaration
- exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
- fde.getNumberOfParameters() = 0
- ) and
+ hasZeroParamDecl(f) and
// Parameter p and its corresponding call argument must have mismatched types
not argMayBeUsed(fc.getArgument(p.getIndex()), p)
-select fc, "Calling $@: argument $@ of type $@ is incompatible with parameter $@.", f, f.toString(),
- fc.getArgument(p.getIndex()) as arg, arg.toString(), arg.getFullyConverted().getType() as type,
- type.toString(), p, p.getTypedName()
+select fc, "Calling $@: argument $@ of type $@ is incompatible with parameter $@", f, f.toString(),
+ fc.getArgument(p.getIndex()) as arg, arg.toString(),
+ arg.getFullyConverted().getType().getUnderlyingType().getUnspecifiedType() as atype,
+ atype.toString(), p, p.getTypedName()
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected
index a9661b060773..897237c6561a 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected
@@ -1,10 +1,16 @@
-| test.c:25:3:25:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:24:3:24:3 | not_yet_declared2 | not_yet_declared2 | test.c:25:21:25:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:45:24:45:26 | p#0 | int p#0 |
-| test.c:25:3:25:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:45:6:45:22 | not_yet_declared2 | not_yet_declared2 | test.c:25:21:25:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:45:24:45:26 | p#0 | int p#0 |
-| test.c:32:3:32:29 | call to declared_empty_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:46:6:46:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:32:31:32:32 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:46:38:46:38 | x | int x |
-| test.c:36:3:36:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:49:6:49:30 | not_declared_defined_with | not_declared_defined_with | test.c:36:37:36:42 | 2500000000.0 | 2500000000.0 | file://:0:0:0:0 | double | double | test.c:49:50:49:50 | z | int z |
-| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:39:26:39:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:61:34:61:34 | x | int * x |
-| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:39:34:39:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:61:43:61:43 | y | void * y |
-| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:61:6:61:27 | declared_with_pointers | declared_with_pointers | test.c:39:26:39:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:61:34:61:34 | x | int * x |
-| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:61:6:61:27 | declared_with_pointers | declared_with_pointers | test.c:39:34:39:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:61:43:61:43 | y | void * y |
-| test.c:41:3:41:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:6:6:6:24 | declared_with_array | declared_with_array | test.c:41:23:41:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:62:31:62:31 | a | char[6] a |
-| test.c:41:3:41:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:62:6:62:24 | declared_with_array | declared_with_array | test.c:41:23:41:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:62:31:62:31 | a | char[6] a |
+| test.c:25:3:25:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:24:3:24:3 | not_yet_declared2 | not_yet_declared2 | test.c:25:21:25:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:54:24:54:26 | p#0 | int p#0 |
+| test.c:25:3:25:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:54:6:54:22 | not_yet_declared2 | not_yet_declared2 | test.c:25:21:25:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:54:24:54:26 | p#0 | int p#0 |
+| test.c:32:3:32:29 | call to declared_empty_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:55:6:55:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:32:31:32:32 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:55:38:55:38 | x | int x |
+| test.c:36:3:36:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:58:6:58:30 | not_declared_defined_with | not_declared_defined_with | test.c:36:29:36:31 | 4 | 4 | file://:0:0:0:0 | long long | long long | test.c:58:36:58:36 | x | int x |
+| test.c:36:3:36:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:58:6:58:30 | not_declared_defined_with | not_declared_defined_with | test.c:36:37:36:42 | 2500000000.0 | 2500000000.0 | file://:0:0:0:0 | double | double | test.c:58:50:58:50 | z | int z |
+| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:39:26:39:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:70:34:70:34 | x | int * x |
+| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:39:34:39:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:70:43:70:43 | y | void * y |
+| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:70:6:70:27 | declared_with_pointers | declared_with_pointers | test.c:39:26:39:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:70:34:70:34 | x | int * x |
+| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:70:6:70:27 | declared_with_pointers | declared_with_pointers | test.c:39:34:39:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:70:43:70:43 | y | void * y |
+| test.c:41:3:41:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:6:6:6:24 | declared_with_array | declared_with_array | test.c:41:23:41:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:71:31:71:31 | a | char[6] a |
+| test.c:41:3:41:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:71:6:71:24 | declared_with_array | declared_with_array | test.c:41:23:41:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:71:31:71:31 | a | char[6] a |
+| test.c:43:3:43:20 | call to defined_with_float | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:73:7:73:24 | defined_with_float | defined_with_float | test.c:43:22:43:24 | 2.0 | 2.0 | file://:0:0:0:0 | double | double | test.c:73:32:73:32 | f | float f |
+| test.c:44:3:44:20 | call to defined_with_float | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:73:7:73:24 | defined_with_float | defined_with_float | test.c:44:22:44:24 | 2.0 | 2.0 | file://:0:0:0:0 | double | double | test.c:73:32:73:32 | f | float f |
+| test.c:47:3:47:21 | call to defined_with_double | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:77:8:77:26 | defined_with_double | defined_with_double | test.c:47:23:47:25 | 99 | 99 | file://:0:0:0:0 | int | int | test.c:77:35:77:35 | d | double d |
+| test.c:49:3:49:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:81:11:81:32 | defined_with_long_long | defined_with_long_long | test.c:49:26:49:28 | 99 | 99 | file://:0:0:0:0 | int | int | test.c:81:44:81:45 | ll | long long ll |
+| test.c:50:3:50:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:81:11:81:32 | defined_with_long_long | defined_with_long_long | test.c:50:26:50:26 | 3 | 3 | file://:0:0:0:0 | int | int | test.c:81:44:81:45 | ll | long long ll |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected
index 6b56644df7ca..0a7da4a539cd 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected
@@ -1,4 +1,4 @@
| test.c:26:3:26:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:24:3:24:3 | not_yet_declared2 | not_yet_declared2 |
-| test.c:26:3:26:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:45:6:45:22 | not_yet_declared2 | not_yet_declared2 |
-| test.c:28:3:28:29 | call to declared_empty_defined_with | This call has fewer arguments than required by $@. | test.c:46:6:46:32 | declared_empty_defined_with | declared_empty_defined_with |
-| test.c:56:10:56:20 | call to dereference | This call has fewer arguments than required by $@. | test.c:59:5:59:15 | dereference | dereference |
+| test.c:26:3:26:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:54:6:54:22 | not_yet_declared2 | not_yet_declared2 |
+| test.c:28:3:28:29 | call to declared_empty_defined_with | This call has fewer arguments than required by $@. | test.c:55:6:55:32 | declared_empty_defined_with | declared_empty_defined_with |
+| test.c:65:10:65:20 | call to dereference | This call has fewer arguments than required by $@. | test.c:68:5:68:15 | dereference | dereference |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected
index 89ae7d04771e..4c10cc7488c0 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected
@@ -1,5 +1,5 @@
| test.c:16:3:16:16 | call to declared_empty | This call has more arguments than required by $@. | test.c:1:6:1:19 | declared_empty | declared_empty |
| test.c:21:3:21:12 | call to undeclared | This call has more arguments than required by $@. | test.c:20:3:20:3 | undeclared | undeclared |
| test.c:23:3:23:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:23:3:23:3 | not_yet_declared1 | not_yet_declared1 |
-| test.c:23:3:23:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:44:6:44:22 | not_yet_declared1 | not_yet_declared1 |
-| test.c:33:3:33:29 | call to declared_empty_defined_with | This call has more arguments than required by $@. | test.c:46:6:46:32 | declared_empty_defined_with | declared_empty_defined_with |
+| test.c:23:3:23:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:53:6:53:22 | not_yet_declared1 | not_yet_declared1 |
+| test.c:33:3:33:29 | call to declared_empty_defined_with | This call has more arguments than required by $@. | test.c:55:6:55:32 | declared_empty_defined_with | declared_empty_defined_with |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c
index 9763d3936afe..beb5dba69c81 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c
@@ -39,6 +39,15 @@ void test() {
declared_with_pointers(3.5e15, 0); // BAD
declared_with_array("Hello"); // GOOD
declared_with_array(&x); // BAD
+
+ defined_with_float(2.f); // BAD
+ defined_with_float(2.0); // BAD
+
+ defined_with_double(2.f); // GOOD
+ defined_with_double('c'); // BAD
+
+ defined_with_long_long('c'); // BAD
+ defined_with_long_long(3); // BAD
}
void not_yet_declared1();
@@ -61,3 +70,15 @@ int dereference(int *x) { return *x; }
void declared_with_pointers(int *x, void *y);
void declared_with_array(char a [6]);
+float defined_with_float(float f) {
+ return f;
+}
+
+double defined_with_double(double d) {
+ return d;
+}
+
+long long defined_with_long_long(long long ll) {
+ return ll;
+}
+
\ No newline at end of file
From d76138f189600f397aeb869ee6908474a9604729 Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Wed, 10 Apr 2019 10:51:22 -0700
Subject: [PATCH 16/27] [CPP-340] Remove use of getUnderlyingType() predicate
as it does not appear necessary. Correct comment to refer to
arguments rather than parameters.
---
.../MistypedFunctionArguments.ql | 10 +++++-----
.../Underspecified Functions/TooManyArguments.ql | 2 +-
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
index 972b7f7c71d7..9d869feab38a 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
@@ -53,10 +53,10 @@ predicate argTypeMayBeUsed(Type arg, Type parm) {
or
// pointers to compatible types
pointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(),
- parm.(PointerType).getBaseType().getUnderlyingType().getUnspecifiedType())
+ parm.(PointerType).getBaseType().getUnspecifiedType())
or
pointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(),
- parm.(ArrayType).getBaseType().getUnderlyingType().getUnspecifiedType())
+ parm.(ArrayType).getBaseType().getUnspecifiedType())
}
// This predicate doesn't necessarily have to exist, but if it does exist
@@ -65,8 +65,8 @@ predicate argTypeMayBeUsed(Type arg, Type parm) {
// Its body could also just be hand-inlined where it's used.
pragma[inline]
predicate argMayBeUsed(Expr arg, Parameter parm) {
- argTypeMayBeUsed(arg.getFullyConverted().getType().getUnderlyingType().getUnspecifiedType(),
- parm.getType().getUnderlyingType().getUnspecifiedType())
+ argTypeMayBeUsed(arg.getFullyConverted().getType().getUnspecifiedType(),
+ parm.getType().getUnspecifiedType())
}
// True if function was ()-declared, but not (void)-declared
@@ -88,5 +88,5 @@ where
not argMayBeUsed(fc.getArgument(p.getIndex()), p)
select fc, "Calling $@: argument $@ of type $@ is incompatible with parameter $@", f, f.toString(),
fc.getArgument(p.getIndex()) as arg, arg.toString(),
- arg.getFullyConverted().getType().getUnderlyingType().getUnspecifiedType() as atype,
+ arg.getFullyConverted().getType().getUnspecifiedType() as atype,
atype.toString(), p, p.getTypedName()
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
index 39684fe3acc5..3ed40c76d3b3 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
@@ -1,5 +1,5 @@
/**
- * @name Call to function with extraneous parameters
+ * @name Call to function with extraneous arguments
* @description A function call to a function passed more arguments than there are
* declared parameters of the function. This may indicate
* that the code does not follow the author's intent.
From b58f414ede7ededa71c0890c504bcb080a8cb379 Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Fri, 12 Apr 2019 17:25:33 -0700
Subject: [PATCH 17/27] [CPP-340] Add more test case; exclude K&R definitions
of functions when looking up ()-declarations; refactor QL code.
---
.../MistypedFunctionArguments.ql | 60 +++++++++++--------
.../TooFewArguments.ql | 23 +++++--
.../TooManyArguments.ql | 21 +++++--
.../MistypedFunctionArguments.expected | 36 ++++++-----
.../TooFewArguments.expected | 8 +--
.../TooManyArguments.expected | 10 ++--
.../Underspecified Functions/test.c | 12 ++++
.../Underspecified Functions/test.cpp | 3 +
8 files changed, 114 insertions(+), 59 deletions(-)
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
index 9d869feab38a..557305d26207 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
@@ -14,23 +14,26 @@
import cpp
-pragma[inline]
-predicate pointerArgTypeMayBeUsed(Type arg, Type parm) {
- arg = parm
- or
- // arithmetic types
+predicate arithTypesMatch(Type arg, Type parm) {
arg instanceof ArithmeticType and
parm instanceof ArithmeticType and
arg.getSize() = parm.getSize() and
(
- arg instanceof IntegralType and
- parm instanceof IntegralType
+ arg instanceof IntegralOrEnumType and
+ parm instanceof IntegralOrEnumType
or
arg instanceof FloatingPointType and
parm instanceof FloatingPointType
)
+}
+pragma[inline]
+predicate pointerArgTypeMayBeUsed(Type arg, Type parm) {
+ arg = parm
or
- // pointers to void are ok
+ // arithmetic types
+ arithTypesMatch(arg, parm)
+ or
+ // conversion to/from pointers to void is allowed
arg instanceof VoidType
or
parm instanceof VoidType
@@ -40,23 +43,22 @@ pragma[inline]
predicate argTypeMayBeUsed(Type arg, Type parm) {
arg = parm
or
- // float arguments will have been promoted to double,
- // and the parameter must match this
- arg instanceof DoubleType and
- parm instanceof DoubleType
- or
- // integral arguments are promoted to int (but not long long).
- arg instanceof IntegralType and
- arg.getSize() = 4 and
- parm instanceof IntegralType and
- parm.getSize() = 4
+ // arithmetic types
+ arithTypesMatch(arg, parm)
or
// pointers to compatible types
pointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(),
parm.(PointerType).getBaseType().getUnspecifiedType())
or
+ pointerArgTypeMayBeUsed(arg.(ArrayType).getBaseType().getUnspecifiedType(),
+ parm.(PointerType).getBaseType().getUnspecifiedType())
+ or
+ // C11 arrays
pointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(),
parm.(ArrayType).getBaseType().getUnspecifiedType())
+ or
+ pointerArgTypeMayBeUsed(arg.(ArrayType).getBaseType().getUnspecifiedType(),
+ parm.(ArrayType).getBaseType().getUnspecifiedType())
}
// This predicate doesn't necessarily have to exist, but if it does exist
@@ -69,11 +71,17 @@ predicate argMayBeUsed(Expr arg, Parameter parm) {
parm.getType().getUnspecifiedType())
}
-// True if function was ()-declared, but not (void)-declared
-pragma[inline]
+// True if function was ()-declared, but not (void)-declared or K&R-defined
predicate hasZeroParamDecl(Function f) {
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
- not fde.hasVoidParamList() and fde.getNumberOfParameters() = 0
+ not fde.hasVoidParamList() and fde.getNumberOfParameters() = 0 and not fde.isDefinition()
+ )
+}
+
+// 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()
)
}
@@ -81,12 +89,14 @@ from FunctionCall fc, Function f, Parameter p
where
f = fc.getTarget() and
p = f.getAParameter() and
+ hasZeroParamDecl(f) and
+ isCompiledAsC(f) and
not f.isVarargs() and
+ not f instanceof BuiltInFunction and
p.getIndex() < fc.getNumberOfArguments() and
- hasZeroParamDecl(f) and
// Parameter p and its corresponding call argument must have mismatched types
not argMayBeUsed(fc.getArgument(p.getIndex()), p)
-select fc, "Calling $@: argument $@ of type $@ is incompatible with parameter $@", f, f.toString(),
+select fc, "Calling $@: argument $@ of type $@ is incompatible with parameter $@.", f, f.toString(),
fc.getArgument(p.getIndex()) as arg, arg.toString(),
- arg.getFullyConverted().getType().getUnspecifiedType() as atype,
- atype.toString(), p, p.getTypedName()
+ arg.getExplicitlyConverted().getType().getUnspecifiedType() as atype, atype.toString(), p,
+ p.getTypedName()
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.ql
index 2a7b9a0e7ab0..c060b0adf9d9 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.ql
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.ql
@@ -15,17 +15,30 @@
import cpp
+// True if function was ()-declared, but not (void)-declared or K&R-defined
+predicate hasZeroParamDecl(Function f) {
+ exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
+ not fde.hasVoidParamList() and fde.getNumberOfParameters() = 0 and not fde.isDefinition()
+ )
+}
+
+// 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()
+ )
+}
+
from FunctionCall fc, Function f
where
f = fc.getTarget() and
not f.isVarargs() and
- // There must be a zero-parameter declaration (explicit or implicit)
- exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
- fde.getNumberOfParameters() = 0
- ) and
+ not f instanceof BuiltInFunction and
+ hasZeroParamDecl(f) and
+ isCompiledAsC(f) and
// There is an explicit declaration of the function whose parameter count is larger
// than the number of call arguments
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
- not fde.isImplicit() and fde.getNumberOfParameters() > fc.getNumberOfArguments()
+ fde.getNumberOfParameters() > fc.getNumberOfArguments()
)
select fc, "This call has fewer arguments than required by $@.", f, f.toString()
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
index 3ed40c76d3b3..ac6313243611 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
@@ -13,14 +13,27 @@
import cpp
+// True if function was ()-declared, but not (void)-declared or K&R-defined
+predicate hasZeroParamDecl(Function f) {
+ exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
+ not fde.hasVoidParamList() and fde.getNumberOfParameters() = 0 and not fde.isDefinition()
+ )
+}
+
+// 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()
+ )
+}
+
from FunctionCall fc, Function f
where
f = fc.getTarget() and
not f.isVarargs() and
- // There must be a zero-parameter declaration (explicit or implicit)
- exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
- fde.getNumberOfParameters() = 0
- ) and
+ not f instanceof BuiltInFunction and
+ hasZeroParamDecl(f) and
+ isCompiledAsC(f) and
// There must not exist a declaration with the number of parameters
// at least as large as the number of call arguments
not exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected
index 897237c6561a..bcbb2f2115b2 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected
@@ -1,16 +1,20 @@
-| test.c:25:3:25:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:24:3:24:3 | not_yet_declared2 | not_yet_declared2 | test.c:25:21:25:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:54:24:54:26 | p#0 | int p#0 |
-| test.c:25:3:25:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:54:6:54:22 | not_yet_declared2 | not_yet_declared2 | test.c:25:21:25:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:54:24:54:26 | p#0 | int p#0 |
-| test.c:32:3:32:29 | call to declared_empty_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:55:6:55:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:32:31:32:32 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:55:38:55:38 | x | int x |
-| test.c:36:3:36:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:58:6:58:30 | not_declared_defined_with | not_declared_defined_with | test.c:36:29:36:31 | 4 | 4 | file://:0:0:0:0 | long long | long long | test.c:58:36:58:36 | x | int x |
-| test.c:36:3:36:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:58:6:58:30 | not_declared_defined_with | not_declared_defined_with | test.c:36:37:36:42 | 2500000000.0 | 2500000000.0 | file://:0:0:0:0 | double | double | test.c:58:50:58:50 | z | int z |
-| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:39:26:39:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:70:34:70:34 | x | int * x |
-| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:39:34:39:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:70:43:70:43 | y | void * y |
-| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:70:6:70:27 | declared_with_pointers | declared_with_pointers | test.c:39:26:39:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:70:34:70:34 | x | int * x |
-| test.c:39:3:39:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:70:6:70:27 | declared_with_pointers | declared_with_pointers | test.c:39:34:39:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:70:43:70:43 | y | void * y |
-| test.c:41:3:41:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:6:6:6:24 | declared_with_array | declared_with_array | test.c:41:23:41:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:71:31:71:31 | a | char[6] a |
-| test.c:41:3:41:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:71:6:71:24 | declared_with_array | declared_with_array | test.c:41:23:41:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:71:31:71:31 | a | char[6] a |
-| test.c:43:3:43:20 | call to defined_with_float | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:73:7:73:24 | defined_with_float | defined_with_float | test.c:43:22:43:24 | 2.0 | 2.0 | file://:0:0:0:0 | double | double | test.c:73:32:73:32 | f | float f |
-| test.c:44:3:44:20 | call to defined_with_float | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:73:7:73:24 | defined_with_float | defined_with_float | test.c:44:22:44:24 | 2.0 | 2.0 | file://:0:0:0:0 | double | double | test.c:73:32:73:32 | f | float f |
-| test.c:47:3:47:21 | call to defined_with_double | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:77:8:77:26 | defined_with_double | defined_with_double | test.c:47:23:47:25 | 99 | 99 | file://:0:0:0:0 | int | int | test.c:77:35:77:35 | d | double d |
-| test.c:49:3:49:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:81:11:81:32 | defined_with_long_long | defined_with_long_long | test.c:49:26:49:28 | 99 | 99 | file://:0:0:0:0 | int | int | test.c:81:44:81:45 | ll | long long ll |
-| test.c:50:3:50:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@ | test.c:81:11:81:32 | defined_with_long_long | defined_with_long_long | test.c:50:26:50:26 | 3 | 3 | file://:0:0:0:0 | int | int | test.c:81:44:81:45 | ll | long long ll |
+| test.c:32:3:32:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:31:3:31:3 | not_yet_declared2 | not_yet_declared2 | test.c:32:21:32:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:66:24:66:26 | p#0 | int p#0 |
+| test.c:32:3:32:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:31:3:31:3 | not_yet_declared2 | not_yet_declared2 | test.c:32:21:32:22 | ca | ca | file://:0:0:0:0 | int[4] | int[4] | test.c:66:24:66:26 | p#0 | int p#0 |
+| test.c:32:3:32:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:66:6:66:22 | not_yet_declared2 | not_yet_declared2 | test.c:32:21:32:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:66:24:66:26 | p#0 | int p#0 |
+| test.c:32:3:32:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:66:6:66:22 | not_yet_declared2 | not_yet_declared2 | test.c:32:21:32:22 | ca | ca | file://:0:0:0:0 | int[4] | int[4] | test.c:66:24:66:26 | p#0 | int p#0 |
+| test.c:39:3:39:29 | call to declared_empty_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:67:6:67:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:39:31:39:32 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:67:38:67:38 | x | int x |
+| test.c:43:3:43:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:70:6:70:30 | not_declared_defined_with | not_declared_defined_with | test.c:43:29:43:31 | 4 | 4 | file://:0:0:0:0 | long long | long long | test.c:70:36:70:36 | x | int x |
+| test.c:43:3:43:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:70:6:70:30 | not_declared_defined_with | not_declared_defined_with | test.c:43:37:43:42 | 2500000000.0 | 2500000000.0 | file://:0:0:0:0 | float | float | test.c:70:50:70:50 | z | int z |
+| test.c:46:3:46:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:46:26:46:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:82:34:82:34 | x | int * x |
+| test.c:46:3:46:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:46:34:46:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:82:43:82:43 | y | void * y |
+| test.c:46:3:46:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:82:6:82:27 | declared_with_pointers | declared_with_pointers | test.c:46:26:46:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:82:34:82:34 | x | int * x |
+| test.c:46:3:46:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:82:6:82:27 | declared_with_pointers | declared_with_pointers | test.c:46:34:46:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:82:43:82:43 | y | void * y |
+| test.c:48:3:48:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:6:6:6:24 | declared_with_array | declared_with_array | test.c:48:23:48:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:83:31:83:31 | a | char[6] a |
+| test.c:48:3:48:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:83:6:83:24 | declared_with_array | declared_with_array | test.c:48:23:48:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:83:31:83:31 | a | char[6] a |
+| test.c:50:3:50:20 | call to defined_with_float | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:85:7:85:24 | defined_with_float | defined_with_float | test.c:50:22:50:24 | 2.0 | 2.0 | file://:0:0:0:0 | float | float | test.c:85:32:85:32 | f | float f |
+| test.c:51:3:51:20 | call to defined_with_float | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:85:7:85:24 | defined_with_float | defined_with_float | test.c:51:22:51:24 | 2.0 | 2.0 | file://:0:0:0:0 | double | double | test.c:85:32:85:32 | f | float f |
+| test.c:54:3:54:21 | call to defined_with_double | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:89:8:89:26 | defined_with_double | defined_with_double | test.c:54:23:54:25 | 99 | 99 | file://:0:0:0:0 | int | int | test.c:89:35:89:35 | d | double d |
+| test.c:56:3:56:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:93:11:93:32 | defined_with_long_long | defined_with_long_long | test.c:56:26:56:28 | 99 | 99 | file://:0:0:0:0 | int | int | test.c:93:44:93:45 | ll | long long ll |
+| test.c:57:3:57:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:93:11:93:32 | defined_with_long_long | defined_with_long_long | test.c:57:26:57:26 | 3 | 3 | file://:0:0:0:0 | int | int | test.c:93:44:93:45 | ll | long long ll |
+| test.c:59:3:59:21 | call to defined_with_double | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:89:8:89:26 | defined_with_double | defined_with_double | test.c:59:23:59:25 | 2 | 2 | file://:0:0:0:0 | long long | long long | test.c:89:35:89:35 | d | double d |
+| test.c:60:3:60:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:93:11:93:32 | defined_with_long_long | defined_with_long_long | test.c:60:26:60:31 | 2.499999999999999983e+50 | 2.499999999999999983e+50 | file://:0:0:0:0 | double | double | test.c:93:44:93:45 | ll | long long ll |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected
index 0a7da4a539cd..1abe1120ba7a 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected
@@ -1,4 +1,4 @@
-| test.c:26:3:26:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:24:3:24:3 | not_yet_declared2 | not_yet_declared2 |
-| test.c:26:3:26:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:54:6:54:22 | not_yet_declared2 | not_yet_declared2 |
-| test.c:28:3:28:29 | call to declared_empty_defined_with | This call has fewer arguments than required by $@. | test.c:55:6:55:32 | declared_empty_defined_with | declared_empty_defined_with |
-| test.c:65:10:65:20 | call to dereference | This call has fewer arguments than required by $@. | test.c:68:5:68:15 | dereference | dereference |
+| test.c:33:3:33:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:31:3:31:3 | not_yet_declared2 | not_yet_declared2 |
+| test.c:33:3:33:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:66:6:66:22 | not_yet_declared2 | not_yet_declared2 |
+| test.c:35:3:35:29 | call to declared_empty_defined_with | This call has fewer arguments than required by $@. | test.c:67:6:67:32 | declared_empty_defined_with | declared_empty_defined_with |
+| test.c:77:10:77:20 | call to dereference | This call has fewer arguments than required by $@. | test.c:80:5:80:15 | dereference | dereference |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected
index 4c10cc7488c0..674928f53ac7 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected
@@ -1,5 +1,5 @@
-| test.c:16:3:16:16 | call to declared_empty | This call has more arguments than required by $@. | test.c:1:6:1:19 | declared_empty | declared_empty |
-| test.c:21:3:21:12 | call to undeclared | This call has more arguments than required by $@. | test.c:20:3:20:3 | undeclared | undeclared |
-| test.c:23:3:23:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:23:3:23:3 | not_yet_declared1 | not_yet_declared1 |
-| test.c:23:3:23:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:53:6:53:22 | not_yet_declared1 | not_yet_declared1 |
-| test.c:33:3:33:29 | call to declared_empty_defined_with | This call has more arguments than required by $@. | test.c:55:6:55:32 | declared_empty_defined_with | declared_empty_defined_with |
+| test.c:23:3:23:16 | call to declared_empty | This call has more arguments than required by $@. | test.c:1:6:1:19 | declared_empty | declared_empty |
+| test.c:28:3:28:12 | call to undeclared | This call has more arguments than required by $@. | test.c:27:3:27:3 | undeclared | undeclared |
+| test.c:30:3:30:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:30:3:30:3 | not_yet_declared1 | not_yet_declared1 |
+| test.c:30:3:30:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:65:6:65:22 | not_yet_declared1 | not_yet_declared1 |
+| test.c:40:3:40:29 | call to declared_empty_defined_with | This call has more arguments than required by $@. | test.c:67:6:67:32 | declared_empty_defined_with | declared_empty_defined_with |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c
index beb5dba69c81..db5b0c5ec26d 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c
@@ -5,6 +5,13 @@ void declared_empty_defined_with();
void declared_with_pointers();
void declared_with_array();
+int k_and_r_func(c,d)
+ char c;
+ double d;
+{
+ return c + d;
+}
+
struct _s { int a, b; } s;
int ca[4] = { 1, 2, 3, 4 };
@@ -48,6 +55,11 @@ void test() {
defined_with_long_long('c'); // BAD
defined_with_long_long(3); // BAD
+
+ defined_with_double(2LL); // BAD
+ defined_with_long_long(2.5e50); // BAD
+
+ k_and_r_func(2.5, &s); // GOOD
}
void not_yet_declared1();
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.cpp b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.cpp
index 855fdaea3fd3..804cd439f2b0 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.cpp
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.cpp
@@ -5,4 +5,7 @@ void test() {
cpp_varargs(); // GOOD
cpp_varargs(1); // GOOD
__builtin_constant_p("something"); // GOOD: builtin
+
+ // The following is marked "good" since we are not supposed
+ // to analyze C++ files.
}
\ No newline at end of file
From 61c91b67aa64b05a3f96e1d3e00e77be382f43b9 Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Sun, 14 Apr 2019 11:31:10 -0700
Subject: [PATCH 18/27] [CPP-340] Refactor MistypedFunctionArguments.ql
further.
---
.../MistypedFunctionArguments.ql | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
index 557305d26207..7ec963d7f0f1 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
@@ -15,8 +15,8 @@
import cpp
predicate arithTypesMatch(Type arg, Type parm) {
- arg instanceof ArithmeticType and
- parm instanceof ArithmeticType and
+ arg = parm
+ or
arg.getSize() = parm.getSize() and
(
arg instanceof IntegralOrEnumType and
@@ -26,10 +26,9 @@ predicate arithTypesMatch(Type arg, Type parm) {
parm instanceof FloatingPointType
)
}
+
pragma[inline]
predicate pointerArgTypeMayBeUsed(Type arg, Type parm) {
- arg = parm
- or
// arithmetic types
arithTypesMatch(arg, parm)
or
@@ -41,8 +40,6 @@ predicate pointerArgTypeMayBeUsed(Type arg, Type parm) {
pragma[inline]
predicate argTypeMayBeUsed(Type arg, Type parm) {
- arg = parm
- or
// arithmetic types
arithTypesMatch(arg, parm)
or
From 65130c40abf1c169e2687eaeb451dac162a6ce4f Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Tue, 16 Apr 2019 14:02:34 -0700
Subject: [PATCH 19/27] [CPP-340] Add white list (for false positive
suppression) to TooManyArguments.ql
---
.../Underspecified Functions/TooManyArguments.ql | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
index ac6313243611..99fca0a5454d 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
@@ -27,13 +27,24 @@ predicate isCompiledAsC(Function f) {
)
}
+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
not f.isVarargs() and
- not f instanceof BuiltInFunction and
hasZeroParamDecl(f) and
isCompiledAsC(f) and
+ not isWhitelisted(f) and
// There must not exist a declaration with the number of parameters
// at least as large as the number of call arguments
not exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
From 62b030d27fce8c4d768d62cea819fbe5c9458e1d Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Thu, 18 Apr 2019 17:56:41 -0700
Subject: [PATCH 20/27] [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.
---
.../ArgumentsToImplicit.c | 9 ++++
.../ArgumentsToImplicit.qhelp | 29 +++++++++++
.../ArgumentsToImplicit.ql | 49 +++++++++++++++++++
.../TooManyArguments.ql | 6 ++-
.../ArgumentsToImplicit.expected | 1 +
.../ArgumentsToImplicit.qlref | 1 +
.../TooManyArguments.expected | 1 -
7 files changed, 94 insertions(+), 2 deletions(-)
create mode 100644 cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.c
create mode 100644 cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.qhelp
create mode 100644 cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.ql
create mode 100644 cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.expected
create mode 100644 cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.qlref
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.c b/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.c
new file mode 100644
index 000000000000..77164b334d30
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.c
@@ -0,0 +1,9 @@
+
+void calls() {
+
+ undeclared(); // GOOD
+
+ undeclared(1); // BAD
+
+ undeclared(1, 2); // BAD
+}
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.qhelp b/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.qhelp
new file mode 100644
index 000000000000..78f12ac6de56
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.qhelp
@@ -0,0 +1,29 @@
+
+
+
+
+
+An implicitly-declared function is called with arguments.
+
+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.
+
+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.
+
+
+
+Call the function without any arguments.
+
+
+
+
+
+
+
+SEI CERT C Coding Standard: DCL20-C. Explicitly specify void when a function accepts no arguments
+
+
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.ql
new file mode 100644
index 000000000000..96bdd36a8e19
--- /dev/null
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.ql
@@ -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()
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
index 99fca0a5454d..e866c6f60500 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
@@ -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()
)
}
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.expected
new file mode 100644
index 000000000000..f1cb25249c26
--- /dev/null
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.expected
@@ -0,0 +1 @@
+| test.c:28:3:28:12 | call to undeclared | This call to an implicitly declared function $@ has arguments. | test.c:27:3:27:3 | undeclared | undeclared |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.qlref b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.qlref
new file mode 100644
index 000000000000..66dc368af6f2
--- /dev/null
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.qlref
@@ -0,0 +1 @@
+Likely Bugs/Underspecified Functions/ArgumentsToImplicit.ql
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected
index 674928f53ac7..7ac6b10070a5 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected
@@ -1,5 +1,4 @@
| test.c:23:3:23:16 | call to declared_empty | This call has more arguments than required by $@. | test.c:1:6:1:19 | declared_empty | declared_empty |
-| test.c:28:3:28:12 | call to undeclared | This call has more arguments than required by $@. | test.c:27:3:27:3 | undeclared | undeclared |
| test.c:30:3:30:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:30:3:30:3 | not_yet_declared1 | not_yet_declared1 |
| test.c:30:3:30:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:65:6:65:22 | not_yet_declared1 | not_yet_declared1 |
| test.c:40:3:40:29 | call to declared_empty_defined_with | This call has more arguments than required by $@. | test.c:67:6:67:32 | declared_empty_defined_with | declared_empty_defined_with |
From 36b2c14f8883150f2ce2695f89ff62effa8e8ead Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Fri, 19 Apr 2019 11:46:54 -0700
Subject: [PATCH 21/27] [CPP-340] Minor formatting tweaks
---
.../Underspecified Functions/ArgumentsToImplicit.ql | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.ql
index 96bdd36a8e19..e3ff53c63054 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.ql
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.ql
@@ -1,7 +1,7 @@
/**
* @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
+ * 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
@@ -16,9 +16,7 @@ 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()
- )
+ not exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() | not fde.isImplicit())
}
// True if this file (or header) was compiled as a C file
From ac58bdfc58f20a446a58ee4591e2f3cf05d67839 Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Wed, 24 Apr 2019 14:54:01 -0700
Subject: [PATCH 22/27] [CPP-340] For MistypedFunctionArguments.ql, add support
for pointers to pointers and pointers to arrays.
---
.../MistypedFunctionArguments.ql | 20 +++++++---
.../TooFewArguments.ql | 7 ++--
.../MistypedFunctionArguments.expected | 40 +++++++++----------
.../TooFewArguments.expected | 6 +--
.../TooManyArguments.expected | 4 +-
.../Underspecified Functions/test.c | 15 ++++++-
6 files changed, 58 insertions(+), 34 deletions(-)
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
index 7ec963d7f0f1..7295b1aa2efe 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
@@ -28,7 +28,7 @@ predicate arithTypesMatch(Type arg, Type parm) {
}
pragma[inline]
-predicate pointerArgTypeMayBeUsed(Type arg, Type parm) {
+predicate nestedPointerArgTypeMayBeUsed(Type arg, Type parm) {
// arithmetic types
arithTypesMatch(arg, parm)
or
@@ -38,6 +38,18 @@ predicate pointerArgTypeMayBeUsed(Type arg, Type parm) {
parm instanceof VoidType
}
+pragma[inline]
+predicate pointerArgTypeMayBeUsed(Type arg, Type parm) {
+ nestedPointerArgTypeMayBeUsed(arg, parm)
+ or
+ // nested pointers
+ nestedPointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(),
+ parm.(PointerType).getBaseType().getUnspecifiedType())
+ or
+ nestedPointerArgTypeMayBeUsed(arg.(ArrayType).getBaseType().getUnspecifiedType(),
+ parm.(PointerType).getBaseType().getUnspecifiedType())
+}
+
pragma[inline]
predicate argTypeMayBeUsed(Type arg, Type parm) {
// arithmetic types
@@ -58,10 +70,8 @@ predicate argTypeMayBeUsed(Type arg, Type parm) {
parm.(ArrayType).getBaseType().getUnspecifiedType())
}
-// This predicate doesn't necessarily have to exist, but if it does exist
-// then it must be inline to make sure we don't enumerate all pairs of
-// compatible types.
-// Its body could also just be hand-inlined where it's used.
+// This predicate holds whenever expression `arg` may be used to initialize
+// function parameter `parm` without need for run-time conversion.
pragma[inline]
predicate argMayBeUsed(Expr arg, Parameter parm) {
argTypeMayBeUsed(arg.getFullyConverted().getType().getUnspecifiedType(),
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.ql
index c060b0adf9d9..134533313ac2 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.ql
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooFewArguments.ql
@@ -1,9 +1,10 @@
/**
* @name Call to function with fewer arguments than declared parameters
- * @description A function call passed fewer arguments than the number of
+ * @description A function call is passing fewer arguments than the number of
* declared parameters of the function. This may indicate
- * that the code does not follow the author's intent. It is also a vulnerability,
- * since the function is like to operate on undefined data.
+ * that the code does not follow the author's intent. It is also
+ * a vulnerability, since the function is likely to operate on
+ * undefined data.
* @kind problem
* @problem.severity error
* @precision very-high
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected
index bcbb2f2115b2..c72471a356a8 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected
@@ -1,20 +1,20 @@
-| test.c:32:3:32:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:31:3:31:3 | not_yet_declared2 | not_yet_declared2 | test.c:32:21:32:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:66:24:66:26 | p#0 | int p#0 |
-| test.c:32:3:32:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:31:3:31:3 | not_yet_declared2 | not_yet_declared2 | test.c:32:21:32:22 | ca | ca | file://:0:0:0:0 | int[4] | int[4] | test.c:66:24:66:26 | p#0 | int p#0 |
-| test.c:32:3:32:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:66:6:66:22 | not_yet_declared2 | not_yet_declared2 | test.c:32:21:32:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:66:24:66:26 | p#0 | int p#0 |
-| test.c:32:3:32:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:66:6:66:22 | not_yet_declared2 | not_yet_declared2 | test.c:32:21:32:22 | ca | ca | file://:0:0:0:0 | int[4] | int[4] | test.c:66:24:66:26 | p#0 | int p#0 |
-| test.c:39:3:39:29 | call to declared_empty_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:67:6:67:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:39:31:39:32 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:67:38:67:38 | x | int x |
-| test.c:43:3:43:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:70:6:70:30 | not_declared_defined_with | not_declared_defined_with | test.c:43:29:43:31 | 4 | 4 | file://:0:0:0:0 | long long | long long | test.c:70:36:70:36 | x | int x |
-| test.c:43:3:43:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:70:6:70:30 | not_declared_defined_with | not_declared_defined_with | test.c:43:37:43:42 | 2500000000.0 | 2500000000.0 | file://:0:0:0:0 | float | float | test.c:70:50:70:50 | z | int z |
-| test.c:46:3:46:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:46:26:46:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:82:34:82:34 | x | int * x |
-| test.c:46:3:46:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:46:34:46:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:82:43:82:43 | y | void * y |
-| test.c:46:3:46:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:82:6:82:27 | declared_with_pointers | declared_with_pointers | test.c:46:26:46:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:82:34:82:34 | x | int * x |
-| test.c:46:3:46:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:82:6:82:27 | declared_with_pointers | declared_with_pointers | test.c:46:34:46:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:82:43:82:43 | y | void * y |
-| test.c:48:3:48:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:6:6:6:24 | declared_with_array | declared_with_array | test.c:48:23:48:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:83:31:83:31 | a | char[6] a |
-| test.c:48:3:48:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:83:6:83:24 | declared_with_array | declared_with_array | test.c:48:23:48:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:83:31:83:31 | a | char[6] a |
-| test.c:50:3:50:20 | call to defined_with_float | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:85:7:85:24 | defined_with_float | defined_with_float | test.c:50:22:50:24 | 2.0 | 2.0 | file://:0:0:0:0 | float | float | test.c:85:32:85:32 | f | float f |
-| test.c:51:3:51:20 | call to defined_with_float | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:85:7:85:24 | defined_with_float | defined_with_float | test.c:51:22:51:24 | 2.0 | 2.0 | file://:0:0:0:0 | double | double | test.c:85:32:85:32 | f | float f |
-| test.c:54:3:54:21 | call to defined_with_double | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:89:8:89:26 | defined_with_double | defined_with_double | test.c:54:23:54:25 | 99 | 99 | file://:0:0:0:0 | int | int | test.c:89:35:89:35 | d | double d |
-| test.c:56:3:56:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:93:11:93:32 | defined_with_long_long | defined_with_long_long | test.c:56:26:56:28 | 99 | 99 | file://:0:0:0:0 | int | int | test.c:93:44:93:45 | ll | long long ll |
-| test.c:57:3:57:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:93:11:93:32 | defined_with_long_long | defined_with_long_long | test.c:57:26:57:26 | 3 | 3 | file://:0:0:0:0 | int | int | test.c:93:44:93:45 | ll | long long ll |
-| test.c:59:3:59:21 | call to defined_with_double | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:89:8:89:26 | defined_with_double | defined_with_double | test.c:59:23:59:25 | 2 | 2 | file://:0:0:0:0 | long long | long long | test.c:89:35:89:35 | d | double d |
-| test.c:60:3:60:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:93:11:93:32 | defined_with_long_long | defined_with_long_long | test.c:60:26:60:31 | 2.499999999999999983e+50 | 2.499999999999999983e+50 | file://:0:0:0:0 | double | double | test.c:93:44:93:45 | ll | long long ll |
+| test.c:32:3:32:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:31:3:31:3 | not_yet_declared2 | not_yet_declared2 | test.c:32:21:32:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:72:24:72:26 | p#0 | int p#0 |
+| test.c:32:3:32:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:31:3:31:3 | not_yet_declared2 | not_yet_declared2 | test.c:32:21:32:22 | ca | ca | file://:0:0:0:0 | int[4] | int[4] | test.c:72:24:72:26 | p#0 | int p#0 |
+| test.c:32:3:32:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:72:6:72:22 | not_yet_declared2 | not_yet_declared2 | test.c:32:21:32:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:72:24:72:26 | p#0 | int p#0 |
+| test.c:32:3:32:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:72:6:72:22 | not_yet_declared2 | not_yet_declared2 | test.c:32:21:32:22 | ca | ca | file://:0:0:0:0 | int[4] | int[4] | test.c:72:24:72:26 | p#0 | int p#0 |
+| test.c:39:3:39:29 | call to declared_empty_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:73:6:73:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:39:31:39:32 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:73:38:73:38 | x | int x |
+| test.c:43:3:43:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:76:6:76:30 | not_declared_defined_with | not_declared_defined_with | test.c:43:29:43:31 | 4 | 4 | file://:0:0:0:0 | long long | long long | test.c:76:36:76:36 | x | int x |
+| test.c:43:3:43:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:76:6:76:30 | not_declared_defined_with | not_declared_defined_with | test.c:43:37:43:42 | 2500000000.0 | 2500000000.0 | file://:0:0:0:0 | float | float | test.c:76:50:76:50 | z | int z |
+| test.c:46:3:46:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:46:26:46:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:88:34:88:34 | x | int * x |
+| test.c:46:3:46:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:46:34:46:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:88:43:88:43 | y | void * y |
+| test.c:46:3:46:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:88:6:88:27 | declared_with_pointers | declared_with_pointers | test.c:46:26:46:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:88:34:88:34 | x | int * x |
+| test.c:46:3:46:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:88:6:88:27 | declared_with_pointers | declared_with_pointers | test.c:46:34:46:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:88:43:88:43 | y | void * y |
+| test.c:48:3:48:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:6:6:6:24 | declared_with_array | declared_with_array | test.c:48:23:48:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:89:31:89:31 | a | char[6] a |
+| test.c:48:3:48:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:89:6:89:24 | declared_with_array | declared_with_array | test.c:48:23:48:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:89:31:89:31 | a | char[6] a |
+| test.c:50:3:50:20 | call to defined_with_float | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:91:7:91:24 | defined_with_float | defined_with_float | test.c:50:22:50:24 | 2.0 | 2.0 | file://:0:0:0:0 | float | float | test.c:91:32:91:32 | f | float f |
+| test.c:51:3:51:20 | call to defined_with_float | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:91:7:91:24 | defined_with_float | defined_with_float | test.c:51:22:51:24 | 2.0 | 2.0 | file://:0:0:0:0 | double | double | test.c:91:32:91:32 | f | float f |
+| test.c:54:3:54:21 | call to defined_with_double | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:95:8:95:26 | defined_with_double | defined_with_double | test.c:54:23:54:25 | 99 | 99 | file://:0:0:0:0 | int | int | test.c:95:35:95:35 | d | double d |
+| test.c:56:3:56:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:99:11:99:32 | defined_with_long_long | defined_with_long_long | test.c:56:26:56:28 | 99 | 99 | file://:0:0:0:0 | int | int | test.c:99:44:99:45 | ll | long long ll |
+| test.c:57:3:57:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:99:11:99:32 | defined_with_long_long | defined_with_long_long | test.c:57:26:57:26 | 3 | 3 | file://:0:0:0:0 | int | int | test.c:99:44:99:45 | ll | long long ll |
+| test.c:59:3:59:21 | call to defined_with_double | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:95:8:95:26 | defined_with_double | defined_with_double | test.c:59:23:59:25 | 2 | 2 | file://:0:0:0:0 | long long | long long | test.c:95:35:95:35 | d | double d |
+| test.c:60:3:60:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:99:11:99:32 | defined_with_long_long | defined_with_long_long | test.c:60:26:60:31 | 2.499999999999999983e+50 | 2.499999999999999983e+50 | file://:0:0:0:0 | double | double | test.c:99:44:99:45 | ll | long long ll |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected
index 1abe1120ba7a..93c25cdfdfe5 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected
@@ -1,4 +1,4 @@
| test.c:33:3:33:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:31:3:31:3 | not_yet_declared2 | not_yet_declared2 |
-| test.c:33:3:33:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:66:6:66:22 | not_yet_declared2 | not_yet_declared2 |
-| test.c:35:3:35:29 | call to declared_empty_defined_with | This call has fewer arguments than required by $@. | test.c:67:6:67:32 | declared_empty_defined_with | declared_empty_defined_with |
-| test.c:77:10:77:20 | call to dereference | This call has fewer arguments than required by $@. | test.c:80:5:80:15 | dereference | dereference |
+| test.c:33:3:33:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:72:6:72:22 | not_yet_declared2 | not_yet_declared2 |
+| test.c:35:3:35:29 | call to declared_empty_defined_with | This call has fewer arguments than required by $@. | test.c:73:6:73:32 | declared_empty_defined_with | declared_empty_defined_with |
+| test.c:83:10:83:20 | call to dereference | This call has fewer arguments than required by $@. | test.c:86:5:86:15 | dereference | dereference |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected
index 7ac6b10070a5..ca421651886e 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected
@@ -1,4 +1,4 @@
| test.c:23:3:23:16 | call to declared_empty | This call has more arguments than required by $@. | test.c:1:6:1:19 | declared_empty | declared_empty |
| test.c:30:3:30:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:30:3:30:3 | not_yet_declared1 | not_yet_declared1 |
-| test.c:30:3:30:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:65:6:65:22 | not_yet_declared1 | not_yet_declared1 |
-| test.c:40:3:40:29 | call to declared_empty_defined_with | This call has more arguments than required by $@. | test.c:67:6:67:32 | declared_empty_defined_with | declared_empty_defined_with |
+| test.c:30:3:30:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:71:6:71:22 | not_yet_declared1 | not_yet_declared1 |
+| test.c:40:3:40:29 | call to declared_empty_defined_with | This call has more arguments than required by $@. | test.c:73:6:73:32 | declared_empty_defined_with | declared_empty_defined_with |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c
index db5b0c5ec26d..a0fa852838a2 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c
@@ -18,7 +18,7 @@ int ca[4] = { 1, 2, 3, 4 };
void *pv;
-void test() {
+void test(int *argv[]) {
declared_empty(); // GOOD
declared_empty(1); // BAD
declared_void(); // GOOD
@@ -60,6 +60,12 @@ void test() {
defined_with_long_long(2.5e50); // BAD
k_and_r_func(2.5, &s); // GOOD
+
+ int (*parameterName)[2];
+ defined_with_ptr_ptr(parameterName); // GOOD
+ defined_with_ptr_ptr(argv); // GOOD
+ defined_with_ptr_arr(parameterName); // GOOD
+ defined_with_ptr_arr(argv); // GOOD
}
void not_yet_declared1();
@@ -93,4 +99,11 @@ double defined_with_double(double d) {
long long defined_with_long_long(long long ll) {
return ll;
}
+
+unsigned int defined_with_ptr_ptr(unsigned int **ptr) {
+ return **ptr;
+}
+unsigned int defined_with_ptr_arr(unsigned int *ptr[]) {
+ return **ptr;
+}
\ No newline at end of file
From 4a760b15610a2aca051967339b11c921c3d22742 Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Sun, 28 Apr 2019 13:49:46 -0700
Subject: [PATCH 23/27] [CPP-340] Delete ArgumentsToImplicit.ql and associated
files. Reduce MistypedFunctionArguments.ql precision to `medium`.
---
.../ArgumentsToImplicit.c | 9 ----
.../ArgumentsToImplicit.qhelp | 29 ------------
.../ArgumentsToImplicit.ql | 47 -------------------
.../MistypedFunctionArguments.ql | 2 +-
.../ArgumentsToImplicit.expected | 1 -
.../ArgumentsToImplicit.qlref | 1 -
6 files changed, 1 insertion(+), 88 deletions(-)
delete mode 100644 cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.c
delete mode 100644 cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.qhelp
delete mode 100644 cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.ql
delete mode 100644 cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.expected
delete mode 100644 cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.qlref
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.c b/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.c
deleted file mode 100644
index 77164b334d30..000000000000
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.c
+++ /dev/null
@@ -1,9 +0,0 @@
-
-void calls() {
-
- undeclared(); // GOOD
-
- undeclared(1); // BAD
-
- undeclared(1, 2); // BAD
-}
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.qhelp b/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.qhelp
deleted file mode 100644
index 78f12ac6de56..000000000000
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.qhelp
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
-
-An implicitly-declared function is called with arguments.
-
-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.
-
-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.
-
-
-
-Call the function without any arguments.
-
-
-
-
-
-
-
-SEI CERT C Coding Standard: DCL20-C. Explicitly specify void when a function accepts no arguments
-
-
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.ql
deleted file mode 100644
index e3ff53c63054..000000000000
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.ql
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * @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()
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
index 7295b1aa2efe..be07c0ea7f16 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
@@ -6,7 +6,7 @@
* arguments on a stack may lead to unpredictable function behavior.
* @kind problem
* @problem.severity warning
- * @precision high
+ * @precision medium
* @id cpp/mistyped-function-arguments
* @tags correctness
* maintainability
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.expected
deleted file mode 100644
index f1cb25249c26..000000000000
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.expected
+++ /dev/null
@@ -1 +0,0 @@
-| test.c:28:3:28:12 | call to undeclared | This call to an implicitly declared function $@ has arguments. | test.c:27:3:27:3 | undeclared | undeclared |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.qlref b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.qlref
deleted file mode 100644
index 66dc368af6f2..000000000000
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/ArgumentsToImplicit.qlref
+++ /dev/null
@@ -1 +0,0 @@
-Likely Bugs/Underspecified Functions/ArgumentsToImplicit.ql
From a0cfe826ee65cc4ab71d05687f170a88d935677e Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Mon, 29 Apr 2019 09:58:31 -0700
Subject: [PATCH 24/27] [CPP-340] Replace whitelist with f.getBlock() test.
Fix doc comment.
---
.../MistypedFunctionArguments.ql | 7 +++----
.../Underspecified Functions/TooManyArguments.ql | 13 +------------
2 files changed, 4 insertions(+), 16 deletions(-)
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
index be07c0ea7f16..320f9f9164d9 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql
@@ -1,9 +1,8 @@
/**
* @name Call to a function with one or more incompatible arguments
- * @description A call to a function with at least one argument whose type does
- * not match the type of the corresponding function parameter. This may indicate
- * that the author is not familiar with the function being called. Passing mistyped
- * arguments on a stack may lead to unpredictable function behavior.
+ * @description When the type of a function argument is not compatible
+ * with the type of the corresponding parameter, it may lead to
+ * unpredictable behavior.
* @kind problem
* @problem.severity warning
* @precision medium
diff --git a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
index e866c6f60500..b0bd7746c157 100644
--- a/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
+++ b/cpp/ql/src/Likely Bugs/Underspecified Functions/TooManyArguments.ql
@@ -31,24 +31,13 @@ predicate isCompiledAsC(Function f) {
)
}
-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
not f.isVarargs() and
hasZeroParamDecl(f) and
isCompiledAsC(f) and
- not isWhitelisted(f) and
+ exists(f.getBlock()) and
// There must not exist a declaration with the number of parameters
// at least as large as the number of call arguments
not exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
From d14696729be29c5838b667a29f520cf512fd5e5f Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Mon, 29 Apr 2019 14:05:58 -0700
Subject: [PATCH 25/27] [CPP-340] Fix end-of-line formatting for our change
notes. Bring back entry accidentally deleted during previous merge.
---
change-notes/1.21/analysis-cpp.md | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/change-notes/1.21/analysis-cpp.md b/change-notes/1.21/analysis-cpp.md
index cc1cc9cbe8f2..f02247a485f4 100644
--- a/change-notes/1.21/analysis-cpp.md
+++ b/change-notes/1.21/analysis-cpp.md
@@ -6,8 +6,8 @@
| **Query** | **Tags** | **Purpose** |
|-----------------------------|-----------|--------------------------------------------------------------------|
-| `()`-declared function called with too few arguments (`cpp/too-few-arguments`) | Correctness | Find all cases where the number of arguments is less than the number of parameters of the function, provided the function is also properly declared/defined elsewhere. |
-| `()`-declared function called with mismatched arguments (`cpp/mismatched-function-arguments`) | Correctness | Find all cases where the types of arguments do not match the types of parameters of the function, provided the function is also properly declared/defined elsewhere. |
+| `()`-declared function called with too few arguments (`cpp/too-few-arguments`) | Correctness | Find all cases where the number of arguments is less than the number of parameters of the function, provided the function is also properly declared/defined elsewhere. |
+| `()`-declared function called with mismatched arguments (`cpp/mismatched-function-arguments`) | Correctness | Find all cases where the types of arguments do not match the types of parameters of the function, provided the function is also properly declared/defined elsewhere. |
## Changes to existing queries
@@ -21,6 +21,7 @@
| Resource not released in destructor (`cpp/resource-not-released-in-destructor`) | Fewer false positive results | Resource allocation and deallocation functions are now determined more accurately. |
| Comparison result is always the same | Fewer false positive results | The range analysis library is now more conservative about floating point values being possibly `NaN` |
| Wrong type of arguments to formatting function (`cpp/wrong-type-format-argument`) | More correct results and fewer false positive results | This query now more accurately identifies wide and non-wide string/character format arguments on different platforms. Platform detection has also been made more accurate for the purposes of this query. |
-| `()`-declared function called with too many arguments (`cpp/futile-params`) | Improved coverage | Query has been generalized to find all cases where the number of arguments exceedes the number of parameters of the function, provided the function is also properly declared/defined elsewhere. |
+| Wrong type of arguments to formatting function (`cpp/wrong-type-format-argument`) | Fewer false positive results | Non-standard uses of %L are now understood. |
+| `()`-declared function called with too many arguments (`cpp/futile-params`) | Improved coverage | Query has been generalized to find all cases where the number of arguments exceedes the number of parameters of the function, provided the function is also properly declared/defined elsewhere. |
## Changes to QL libraries
From be77eb7367e6c4a638d12cbe617c931a70739c43 Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Mon, 29 Apr 2019 15:30:28 -0700
Subject: [PATCH 26/27] [CPP-340] Add new test cases to test.c; this required
the .expected files to be regenerated.
---
.../MistypedFunctionArguments.expected | 40 +++++++++----------
.../TooFewArguments.expected | 8 ++--
.../TooManyArguments.expected | 6 +--
.../Underspecified Functions/test.c | 11 ++++-
4 files changed, 35 insertions(+), 30 deletions(-)
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected
index c72471a356a8..6ba72c8cda1e 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.expected
@@ -1,20 +1,20 @@
-| test.c:32:3:32:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:31:3:31:3 | not_yet_declared2 | not_yet_declared2 | test.c:32:21:32:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:72:24:72:26 | p#0 | int p#0 |
-| test.c:32:3:32:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:31:3:31:3 | not_yet_declared2 | not_yet_declared2 | test.c:32:21:32:22 | ca | ca | file://:0:0:0:0 | int[4] | int[4] | test.c:72:24:72:26 | p#0 | int p#0 |
-| test.c:32:3:32:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:72:6:72:22 | not_yet_declared2 | not_yet_declared2 | test.c:32:21:32:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:72:24:72:26 | p#0 | int p#0 |
-| test.c:32:3:32:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:72:6:72:22 | not_yet_declared2 | not_yet_declared2 | test.c:32:21:32:22 | ca | ca | file://:0:0:0:0 | int[4] | int[4] | test.c:72:24:72:26 | p#0 | int p#0 |
-| test.c:39:3:39:29 | call to declared_empty_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:73:6:73:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:39:31:39:32 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:73:38:73:38 | x | int x |
-| test.c:43:3:43:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:76:6:76:30 | not_declared_defined_with | not_declared_defined_with | test.c:43:29:43:31 | 4 | 4 | file://:0:0:0:0 | long long | long long | test.c:76:36:76:36 | x | int x |
-| test.c:43:3:43:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:76:6:76:30 | not_declared_defined_with | not_declared_defined_with | test.c:43:37:43:42 | 2500000000.0 | 2500000000.0 | file://:0:0:0:0 | float | float | test.c:76:50:76:50 | z | int z |
-| test.c:46:3:46:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:46:26:46:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:88:34:88:34 | x | int * x |
-| test.c:46:3:46:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:46:34:46:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:88:43:88:43 | y | void * y |
-| test.c:46:3:46:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:88:6:88:27 | declared_with_pointers | declared_with_pointers | test.c:46:26:46:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:88:34:88:34 | x | int * x |
-| test.c:46:3:46:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:88:6:88:27 | declared_with_pointers | declared_with_pointers | test.c:46:34:46:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:88:43:88:43 | y | void * y |
-| test.c:48:3:48:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:6:6:6:24 | declared_with_array | declared_with_array | test.c:48:23:48:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:89:31:89:31 | a | char[6] a |
-| test.c:48:3:48:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:89:6:89:24 | declared_with_array | declared_with_array | test.c:48:23:48:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:89:31:89:31 | a | char[6] a |
-| test.c:50:3:50:20 | call to defined_with_float | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:91:7:91:24 | defined_with_float | defined_with_float | test.c:50:22:50:24 | 2.0 | 2.0 | file://:0:0:0:0 | float | float | test.c:91:32:91:32 | f | float f |
-| test.c:51:3:51:20 | call to defined_with_float | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:91:7:91:24 | defined_with_float | defined_with_float | test.c:51:22:51:24 | 2.0 | 2.0 | file://:0:0:0:0 | double | double | test.c:91:32:91:32 | f | float f |
-| test.c:54:3:54:21 | call to defined_with_double | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:95:8:95:26 | defined_with_double | defined_with_double | test.c:54:23:54:25 | 99 | 99 | file://:0:0:0:0 | int | int | test.c:95:35:95:35 | d | double d |
-| test.c:56:3:56:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:99:11:99:32 | defined_with_long_long | defined_with_long_long | test.c:56:26:56:28 | 99 | 99 | file://:0:0:0:0 | int | int | test.c:99:44:99:45 | ll | long long ll |
-| test.c:57:3:57:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:99:11:99:32 | defined_with_long_long | defined_with_long_long | test.c:57:26:57:26 | 3 | 3 | file://:0:0:0:0 | int | int | test.c:99:44:99:45 | ll | long long ll |
-| test.c:59:3:59:21 | call to defined_with_double | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:95:8:95:26 | defined_with_double | defined_with_double | test.c:59:23:59:25 | 2 | 2 | file://:0:0:0:0 | long long | long long | test.c:95:35:95:35 | d | double d |
-| test.c:60:3:60:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:99:11:99:32 | defined_with_long_long | defined_with_long_long | test.c:60:26:60:31 | 2.499999999999999983e+50 | 2.499999999999999983e+50 | file://:0:0:0:0 | double | double | test.c:99:44:99:45 | ll | long long ll |
+| test.c:33:3:33:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:32:3:32:3 | not_yet_declared2 | not_yet_declared2 | test.c:33:21:33:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:76:24:76:26 | p#0 | int p#0 |
+| test.c:33:3:33:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:32:3:32:3 | not_yet_declared2 | not_yet_declared2 | test.c:33:21:33:22 | ca | ca | file://:0:0:0:0 | int[4] | int[4] | test.c:76:24:76:26 | p#0 | int p#0 |
+| test.c:33:3:33:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:76:6:76:22 | not_yet_declared2 | not_yet_declared2 | test.c:33:21:33:22 | ca | ca | file://:0:0:0:0 | int * | int * | test.c:76:24:76:26 | p#0 | int p#0 |
+| test.c:33:3:33:19 | call to not_yet_declared2 | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:76:6:76:22 | not_yet_declared2 | not_yet_declared2 | test.c:33:21:33:22 | ca | ca | file://:0:0:0:0 | int[4] | int[4] | test.c:76:24:76:26 | p#0 | int p#0 |
+| test.c:40:3:40:29 | call to declared_empty_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:77:6:77:32 | declared_empty_defined_with | declared_empty_defined_with | test.c:40:31:40:32 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:77:38:77:38 | x | int x |
+| test.c:44:3:44:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:80:6:80:30 | not_declared_defined_with | not_declared_defined_with | test.c:44:29:44:31 | 4 | 4 | file://:0:0:0:0 | long long | long long | test.c:80:36:80:36 | x | int x |
+| test.c:44:3:44:27 | call to not_declared_defined_with | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:80:6:80:30 | not_declared_defined_with | not_declared_defined_with | test.c:44:37:44:42 | 2500000000.0 | 2500000000.0 | file://:0:0:0:0 | float | float | test.c:80:50:80:50 | z | int z |
+| test.c:47:3:47:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:47:26:47:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:92:34:92:34 | x | int * x |
+| test.c:47:3:47:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:5:6:5:27 | declared_with_pointers | declared_with_pointers | test.c:47:34:47:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:92:43:92:43 | y | void * y |
+| test.c:47:3:47:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:92:6:92:27 | declared_with_pointers | declared_with_pointers | test.c:47:26:47:31 | 3500000000000000.0 | 3500000000000000.0 | file://:0:0:0:0 | double | double | test.c:92:34:92:34 | x | int * x |
+| test.c:47:3:47:24 | call to declared_with_pointers | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:92:6:92:27 | declared_with_pointers | declared_with_pointers | test.c:47:34:47:34 | 0 | 0 | file://:0:0:0:0 | int | int | test.c:92:43:92:43 | y | void * y |
+| test.c:49:3:49:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:6:6:6:24 | declared_with_array | declared_with_array | test.c:49:23:49:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:93:31:93:31 | a | char[6] a |
+| test.c:49:3:49:21 | call to declared_with_array | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:93:6:93:24 | declared_with_array | declared_with_array | test.c:49:23:49:24 | & ... | & ... | file://:0:0:0:0 | int * | int * | test.c:93:31:93:31 | a | char[6] a |
+| test.c:51:3:51:20 | call to defined_with_float | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:95:7:95:24 | defined_with_float | defined_with_float | test.c:51:22:51:24 | 2.0 | 2.0 | file://:0:0:0:0 | float | float | test.c:95:32:95:32 | f | float f |
+| test.c:52:3:52:20 | call to defined_with_float | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:95:7:95:24 | defined_with_float | defined_with_float | test.c:52:22:52:24 | 2.0 | 2.0 | file://:0:0:0:0 | double | double | test.c:95:32:95:32 | f | float f |
+| test.c:55:3:55:21 | call to defined_with_double | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:99:8:99:26 | defined_with_double | defined_with_double | test.c:55:23:55:25 | 99 | 99 | file://:0:0:0:0 | int | int | test.c:99:35:99:35 | d | double d |
+| test.c:57:3:57:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:103:11:103:32 | defined_with_long_long | defined_with_long_long | test.c:57:26:57:28 | 99 | 99 | file://:0:0:0:0 | int | int | test.c:103:44:103:45 | ll | long long ll |
+| test.c:58:3:58:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:103:11:103:32 | defined_with_long_long | defined_with_long_long | test.c:58:26:58:26 | 3 | 3 | file://:0:0:0:0 | int | int | test.c:103:44:103:45 | ll | long long ll |
+| test.c:60:3:60:21 | call to defined_with_double | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:99:8:99:26 | defined_with_double | defined_with_double | test.c:60:23:60:25 | 2 | 2 | file://:0:0:0:0 | long long | long long | test.c:99:35:99:35 | d | double d |
+| test.c:61:3:61:24 | call to defined_with_long_long | Calling $@: argument $@ of type $@ is incompatible with parameter $@. | test.c:103:11:103:32 | defined_with_long_long | defined_with_long_long | test.c:61:26:61:31 | 2.499999999999999983e+50 | 2.499999999999999983e+50 | file://:0:0:0:0 | double | double | test.c:103:44:103:45 | ll | long long ll |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected
index 93c25cdfdfe5..42c4f7f94559 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooFewArguments.expected
@@ -1,4 +1,4 @@
-| test.c:33:3:33:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:31:3:31:3 | not_yet_declared2 | not_yet_declared2 |
-| test.c:33:3:33:19 | call to not_yet_declared2 | This call has fewer arguments than required by $@. | test.c:72:6:72:22 | not_yet_declared2 | not_yet_declared2 |
-| test.c:35:3:35:29 | call to declared_empty_defined_with | This call has fewer arguments than required by $@. | test.c:73:6:73:32 | declared_empty_defined_with | declared_empty_defined_with |
-| test.c:83:10:83:20 | call to dereference | This call has fewer arguments than required by $@. | test.c:86:5:86:15 | dereference | dereference |
+| 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 |
+| test.c:36:3:36:29 | call to declared_empty_defined_with | This call has fewer arguments than required by $@. | test.c:77:6:77:32 | declared_empty_defined_with | declared_empty_defined_with |
+| test.c:87:10:87:20 | call to dereference | This call has fewer arguments than required by $@. | test.c:90:5:90:15 | dereference | dereference |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected
index ca421651886e..bc64434578b2 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/TooManyArguments.expected
@@ -1,4 +1,2 @@
-| test.c:23:3:23:16 | call to declared_empty | This call has more arguments than required by $@. | test.c:1:6:1:19 | declared_empty | declared_empty |
-| test.c:30:3:30:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:30:3:30:3 | not_yet_declared1 | not_yet_declared1 |
-| test.c:30:3:30:19 | call to not_yet_declared1 | This call has more arguments than required by $@. | test.c:71:6:71:22 | not_yet_declared1 | not_yet_declared1 |
-| test.c:40:3:40:29 | call to declared_empty_defined_with | This call has more arguments than required by $@. | test.c:73:6:73:32 | declared_empty_defined_with | declared_empty_defined_with |
+| test.c:41:3:41:29 | call to declared_empty_defined_with | This call has more arguments than required by $@. | test.c:77:6:77:32 | declared_empty_defined_with | declared_empty_defined_with |
+| test.c:72:3:72:28 | call to declared_and_defined_empty | This call has more arguments than required by $@. | test.c:114:6:114:31 | declared_and_defined_empty | declared_and_defined_empty |
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c
index a0fa852838a2..0c9c6320eaa0 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c
@@ -4,6 +4,7 @@ void declared_with(int);
void declared_empty_defined_with();
void declared_with_pointers();
void declared_with_array();
+void declared_and_defined_empty();
int k_and_r_func(c,d)
char c;
@@ -20,7 +21,7 @@ void *pv;
void test(int *argv[]) {
declared_empty(); // GOOD
- declared_empty(1); // BAD
+ declared_empty(1); // GOOD
declared_void(); // GOOD
declared_with(1); // GOOD
@@ -66,6 +67,9 @@ void test(int *argv[]) {
defined_with_ptr_ptr(argv); // GOOD
defined_with_ptr_arr(parameterName); // GOOD
defined_with_ptr_arr(argv); // GOOD
+
+ declared_and_defined_empty(); // GOOD
+ declared_and_defined_empty(1); // BAD
}
void not_yet_declared1();
@@ -106,4 +110,7 @@ unsigned int defined_with_ptr_ptr(unsigned int **ptr) {
unsigned int defined_with_ptr_arr(unsigned int *ptr[]) {
return **ptr;
}
-
\ No newline at end of file
+
+void declared_and_defined_empty() {
+ return;
+}
From 17066cfe3ee420cdf0cba57bfeac8ee2f7cb3c17 Mon Sep 17 00:00:00 2001
From: Ziemowit Laski
Date: Tue, 30 Apr 2019 13:21:36 -0700
Subject: [PATCH 27/27] [CPP-340] Adjust annotations in test.c file.
---
.../query-tests/Likely Bugs/Underspecified Functions/test.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c
index 0c9c6320eaa0..f58aa823ad8f 100644
--- a/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c
+++ b/cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c
@@ -26,9 +26,9 @@ void test(int *argv[]) {
declared_with(1); // GOOD
undeclared(); // GOOD
- undeclared(1); // BAD
+ undeclared(1); // GOOD
- not_yet_declared1(1); // BAD
+ not_yet_declared1(1); // GOOD
not_yet_declared2(1); // GOOD
not_yet_declared2(ca); // BAD
not_yet_declared2(); // BAD