Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit dc74978

Browse files
committed
[CPP-340] Make the query more strict (again).
1 parent ef54b01 commit dc74978

5 files changed

Lines changed: 72 additions & 36 deletions

File tree

cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,11 @@ predicate pointerArgTypeMayBeUsed(Type arg, Type parm) {
2323
parm instanceof ArithmeticType and
2424
arg.getSize() = parm.getSize() and
2525
(
26-
(
27-
arg instanceof IntegralType and
28-
parm instanceof IntegralType
29-
)
26+
arg instanceof IntegralType and
27+
parm instanceof IntegralType
3028
or
31-
(
32-
arg instanceof FloatingPointType and
33-
parm instanceof FloatingPointType
34-
)
29+
arg instanceof FloatingPointType and
30+
parm instanceof FloatingPointType
3531
)
3632
or
3733
// pointers to void are ok
@@ -44,16 +40,23 @@ pragma[inline]
4440
predicate argTypeMayBeUsed(Type arg, Type parm) {
4541
arg = parm
4642
or
47-
// we treat signed and unsigned versions of integer types as compatible.
43+
// float arguments will have been promoted to double,
44+
// and the parameter must match this
45+
arg instanceof DoubleType and
46+
parm instanceof DoubleType
47+
or
48+
// integral arguments are promoted to int (but not long long).
4849
arg instanceof IntegralType and
49-
parm instanceof IntegralType
50+
arg.getSize() = 4 and
51+
parm instanceof IntegralType and
52+
parm.getSize() = 4
5053
or
5154
// pointers to compatible types
5255
pointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(),
53-
parm.(PointerType).getBaseType().getUnspecifiedType())
56+
parm.(PointerType).getBaseType().getUnderlyingType().getUnspecifiedType())
5457
or
5558
pointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(),
56-
parm.(ArrayType).getBaseType().getUnspecifiedType())
59+
parm.(ArrayType).getBaseType().getUnderlyingType().getUnspecifiedType())
5760
}
5861

5962
// This predicate doesn't necessarily have to exist, but if it does exist
@@ -62,8 +65,16 @@ predicate argTypeMayBeUsed(Type arg, Type parm) {
6265
// Its body could also just be hand-inlined where it's used.
6366
pragma[inline]
6467
predicate argMayBeUsed(Expr arg, Parameter parm) {
65-
argTypeMayBeUsed(arg.getFullyConverted().getType().getUnspecifiedType(),
66-
parm.getType().getUnspecifiedType())
68+
argTypeMayBeUsed(arg.getFullyConverted().getType().getUnderlyingType().getUnspecifiedType(),
69+
parm.getType().getUnderlyingType().getUnspecifiedType())
70+
}
71+
72+
// True if function was ()-declared, but not (void)-declared
73+
pragma[inline]
74+
predicate hasZeroParamDecl(Function f) {
75+
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
76+
not fde.hasVoidParamList() and fde.getNumberOfParameters() = 0
77+
)
6778
}
6879

6980
from FunctionCall fc, Function f, Parameter p
@@ -72,12 +83,10 @@ where
7283
p = f.getAParameter() and
7384
not f.isVarargs() and
7485
p.getIndex() < fc.getNumberOfArguments() and
75-
// There must be a zero-parameter declaration
76-
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
77-
fde.getNumberOfParameters() = 0
78-
) and
86+
hasZeroParamDecl(f) and
7987
// Parameter p and its corresponding call argument must have mismatched types
8088
not argMayBeUsed(fc.getArgument(p.getIndex()), p)
81-
select fc, "Calling $@: argument $@ of type $@ is incompatible with parameter $@.", f, f.toString(),
82-
fc.getArgument(p.getIndex()) as arg, arg.toString(), arg.getFullyConverted().getType() as type,
83-
type.toString(), p, p.getTypedName()
89+
select fc, "Calling $@: argument $@ of type $@ is incompatible with parameter $@", f, f.toString(),
90+
fc.getArgument(p.getIndex()) as arg, arg.toString(),
91+
arg.getFullyConverted().getType().getUnderlyingType().getUnspecifiedType() as atype,
92+
atype.toString(), p, p.getTypedName()
Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1-
| 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 |
2-
| 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 |
3-
| 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 |
4-
| 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 |
5-
| 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 |
6-
| 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 |
7-
| 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 |
8-
| 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 |
9-
| 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 |
10-
| 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 |
1+
| 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 |
2+
| 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 |
3+
| 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 |
4+
| 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 |
5+
| 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 |
6+
| 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 |
7+
| 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 |
8+
| 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 |
9+
| 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 |
10+
| 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 |
11+
| 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 |
12+
| 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 |
13+
| 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 |
14+
| 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 |
15+
| 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 |
16+
| 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 |
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
| 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 |
2-
| 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 |
3-
| 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 |
4-
| 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 |
2+
| 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 |
3+
| 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 |
4+
| 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 |
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
| 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 |
22
| 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 |
33
| 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 |
4-
| 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 |
5-
| 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 |
4+
| 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 |
5+
| 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 |

cpp/ql/test/query-tests/Likely Bugs/Underspecified Functions/test.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,15 @@ void test() {
3939
declared_with_pointers(3.5e15, 0); // BAD
4040
declared_with_array("Hello"); // GOOD
4141
declared_with_array(&x); // BAD
42+
43+
defined_with_float(2.f); // BAD
44+
defined_with_float(2.0); // BAD
45+
46+
defined_with_double(2.f); // GOOD
47+
defined_with_double('c'); // BAD
48+
49+
defined_with_long_long('c'); // BAD
50+
defined_with_long_long(3); // BAD
4251
}
4352

4453
void not_yet_declared1();
@@ -61,3 +70,15 @@ int dereference(int *x) { return *x; }
6170
void declared_with_pointers(int *x, void *y);
6271
void declared_with_array(char a [6]);
6372

73+
float defined_with_float(float f) {
74+
return f;
75+
}
76+
77+
double defined_with_double(double d) {
78+
return d;
79+
}
80+
81+
long long defined_with_long_long(long long ll) {
82+
return ll;
83+
}
84+

0 commit comments

Comments
 (0)