|
13 | 13 |
|
14 | 14 | import cpp
|
15 | 15 | import codingstandards.c.cert
|
| 16 | +import codingstandards.cpp.MistypedFunctionArguments |
16 | 17 |
|
17 |
| -pragma[inline] |
18 |
| -private predicate arithTypesMatch(Type arg, Type parm) { |
19 |
| - arg = parm |
20 |
| - or |
21 |
| - arg.getSize() = parm.getSize() and |
22 |
| - ( |
23 |
| - arg instanceof IntegralOrEnumType and |
24 |
| - parm instanceof IntegralOrEnumType |
25 |
| - or |
26 |
| - arg instanceof FloatingPointType and |
27 |
| - parm instanceof FloatingPointType |
28 |
| - ) |
29 |
| -} |
30 |
| - |
31 |
| -pragma[inline] |
32 |
| -private predicate nestedPointerArgTypeMayBeUsed(Type arg, Type parm) { |
33 |
| - // arithmetic types |
34 |
| - arithTypesMatch(arg, parm) |
35 |
| - or |
36 |
| - // conversion to/from pointers to void is allowed |
37 |
| - arg instanceof VoidType |
38 |
| - or |
39 |
| - parm instanceof VoidType |
40 |
| -} |
41 |
| - |
42 |
| -pragma[inline] |
43 |
| -private predicate pointerArgTypeMayBeUsed(Type arg, Type parm) { |
44 |
| - nestedPointerArgTypeMayBeUsed(arg, parm) |
45 |
| - or |
46 |
| - // nested pointers |
47 |
| - nestedPointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(), |
48 |
| - parm.(PointerType).getBaseType().getUnspecifiedType()) |
49 |
| - or |
50 |
| - nestedPointerArgTypeMayBeUsed(arg.(ArrayType).getBaseType().getUnspecifiedType(), |
51 |
| - parm.(PointerType).getBaseType().getUnspecifiedType()) |
52 |
| -} |
53 |
| - |
54 |
| -pragma[inline] |
55 |
| -private predicate argTypeMayBeUsed(Type arg, Type parm) { |
56 |
| - // arithmetic types |
57 |
| - arithTypesMatch(arg, parm) |
58 |
| - or |
59 |
| - // pointers to compatible types |
60 |
| - pointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(), |
61 |
| - parm.(PointerType).getBaseType().getUnspecifiedType()) |
62 |
| - or |
63 |
| - pointerArgTypeMayBeUsed(arg.(ArrayType).getBaseType().getUnspecifiedType(), |
64 |
| - parm.(PointerType).getBaseType().getUnspecifiedType()) |
65 |
| - or |
66 |
| - // C11 arrays |
67 |
| - pointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(), |
68 |
| - parm.(ArrayType).getBaseType().getUnspecifiedType()) |
69 |
| - or |
70 |
| - pointerArgTypeMayBeUsed(arg.(ArrayType).getBaseType().getUnspecifiedType(), |
71 |
| - parm.(ArrayType).getBaseType().getUnspecifiedType()) |
72 |
| -} |
73 |
| - |
74 |
| -// This predicate holds whenever expression `arg` may be used to initialize |
75 |
| -// function parameter `parm` without need for run-time conversion. |
76 |
| -pragma[inline] |
77 |
| -private predicate argMayBeUsed(Expr arg, Parameter parm) { |
78 |
| - argTypeMayBeUsed(arg.getFullyConverted().getUnspecifiedType(), parm.getUnspecifiedType()) |
79 |
| -} |
80 |
| - |
81 |
| -// True if function was ()-declared, but not (void)-declared or K&R-defined |
82 |
| -private predicate hasZeroParamDecl(Function f) { |
83 |
| - exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() | |
84 |
| - not fde.hasVoidParamList() and fde.getNumberOfParameters() = 0 and not fde.isDefinition() |
85 |
| - ) |
86 |
| -} |
87 |
| - |
88 |
| -// True if this file (or header) was compiled as a C file |
89 |
| -private predicate isCompiledAsC(File f) { |
90 |
| - f.compiledAsC() |
91 |
| - or |
92 |
| - exists(File src | isCompiledAsC(src) | src.getAnIncludedFile() = f) |
93 |
| -} |
94 |
| - |
95 |
| -predicate mistypedFunctionArguments(FunctionCall fc, Function f, Parameter p) { |
96 |
| - f = fc.getTarget() and |
97 |
| - p = f.getAParameter() and |
98 |
| - hasZeroParamDecl(f) and |
99 |
| - isCompiledAsC(f.getFile()) and |
100 |
| - not f.isVarargs() and |
101 |
| - not f instanceof BuiltInFunction and |
102 |
| - p.getIndex() < fc.getNumberOfArguments() and |
103 |
| - // Parameter p and its corresponding call argument must have mismatched types |
104 |
| - not argMayBeUsed(fc.getArgument(p.getIndex()), p) |
105 |
| -} |
106 |
| - |
107 |
| -// The implementation of this query was taken from the following standard library query: |
108 |
| -// codeql/cpp/ql/src/Likely Bugs/Underspecified Functions/MistypedFunctionArguments.ql |
109 | 18 | from FunctionCall fc, Function f, Parameter p
|
110 | 19 | where
|
111 | 20 | not isExcluded(fc, ExpressionsPackage::doNotCallFunctionsWithIncompatibleArgumentsQuery()) and
|
112 |
| - mistypedFunctionArguments(fc, f, p) |
| 21 | + ( |
| 22 | + mistypedFunctionArguments(fc, f, p) |
| 23 | + or |
| 24 | + complexArgumentPassedToRealParameter(fc, f, p) |
| 25 | + ) |
113 | 26 | select fc, "Argument $@ in call to $@ is incompatible with parameter $@.",
|
114 | 27 | fc.getArgument(p.getIndex()) as arg, arg.toString(), f, f.toString(), p, p.getTypedName()
|
0 commit comments