Skip to content

Commit 1bc3829

Browse files
committed
C++: Use newly created library versions of the 'Underspecified Functions' queries in new ImplicitFunctionDeclaration query
1 parent acb106b commit 1bc3829

1 file changed

Lines changed: 12 additions & 129 deletions

File tree

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

Lines changed: 12 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -12,147 +12,30 @@
1212
*/
1313

1414
import cpp
15+
import MistypedFunctionArguments
16+
import TooFewArguments
17+
import TooManyArguments
18+
import semmle.code.cpp.commons.Exclusions
1519

16-
pragma[inline]
17-
predicate arithTypesMatch(Type arg, Type parm) {
18-
arg = parm
19-
or
20-
arg.getSize() = parm.getSize() and
21-
(
22-
arg instanceof IntegralOrEnumType and
23-
parm instanceof IntegralOrEnumType
24-
or
25-
arg instanceof FloatingPointType and
26-
parm instanceof FloatingPointType
27-
)
28-
}
29-
30-
pragma[inline]
31-
predicate nestedPointerArgTypeMayBeUsed(Type arg, Type parm) {
32-
// arithmetic types
33-
arithTypesMatch(arg, parm)
34-
or
35-
// conversion to/from pointers to void is allowed
36-
arg instanceof VoidType
37-
or
38-
parm instanceof VoidType
39-
}
40-
41-
pragma[inline]
42-
predicate pointerArgTypeMayBeUsed(Type arg, Type parm) {
43-
nestedPointerArgTypeMayBeUsed(arg, parm)
44-
or
45-
// nested pointers
46-
nestedPointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(),
47-
parm.(PointerType).getBaseType().getUnspecifiedType())
48-
or
49-
nestedPointerArgTypeMayBeUsed(arg.(ArrayType).getBaseType().getUnspecifiedType(),
50-
parm.(PointerType).getBaseType().getUnspecifiedType())
51-
}
52-
53-
pragma[inline]
54-
predicate argTypeMayBeUsed(Type arg, Type parm) {
55-
// arithmetic types
56-
arithTypesMatch(arg, parm)
57-
or
58-
// pointers to compatible types
59-
pointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(),
60-
parm.(PointerType).getBaseType().getUnspecifiedType())
61-
or
62-
pointerArgTypeMayBeUsed(arg.(ArrayType).getBaseType().getUnspecifiedType(),
63-
parm.(PointerType).getBaseType().getUnspecifiedType())
64-
or
65-
// C11 arrays
66-
pointerArgTypeMayBeUsed(arg.(PointerType).getBaseType().getUnspecifiedType(),
67-
parm.(ArrayType).getBaseType().getUnspecifiedType())
68-
or
69-
pointerArgTypeMayBeUsed(arg.(ArrayType).getBaseType().getUnspecifiedType(),
70-
parm.(ArrayType).getBaseType().getUnspecifiedType())
71-
}
72-
73-
// This predicate holds whenever expression `arg` may be used to initialize
74-
// function parameter `parm` without need for run-time conversion.
75-
pragma[inline]
76-
predicate argMayBeUsed(Expr arg, ParameterDeclarationEntry pde) {
77-
argTypeMayBeUsed(arg.getFullyConverted().getUnspecifiedType(), pde.getUnspecifiedType())
20+
predicate sameLocation(Location loc1, Location loc2) {
21+
loc1.getFile() = loc2.getFile() and
22+
loc1.getStartLine() = loc2.getStartLine() and
23+
loc1.getStartColumn() = loc2.getStartColumn()
7824
}
7925

80-
// True if this file (or header) was compiled as a C file
8126
predicate isCompiledAsC(File f) {
8227
f.compiledAsC()
8328
or
8429
exists(File src | isCompiledAsC(src) | src.getAnIncludedFile() = f)
8530
}
8631

87-
// True if function was ()-declared, but not (void)-declared or K&R-defined
88-
// or implicitly declared (i.e., lacking a prototype)
89-
predicate hasZeroParamDeclTooMany(Function f) {
90-
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
91-
not fde.isImplicit() and
92-
not fde.hasVoidParamList() and
93-
fde.getNumberOfParameters() = 0 and
94-
not fde.isDefinition()
95-
)
96-
}
97-
98-
// True if function was ()-declared, but not (void)-declared or K&R-defined
99-
predicate hasZeroParamDecl(Function f) {
100-
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
101-
not fde.hasVoidParamList() and fde.getNumberOfParameters() = 0 and not fde.isDefinition()
102-
)
103-
}
104-
105-
bindingset[name]
106-
predicate notAlreadyReported(string name, FunctionCall fc) {
107-
forall(FunctionDeclarationEntry fdeEx |
108-
fdeEx.getName() = name and
109-
not fdeEx.isImplicit()
110-
|
111-
// only report if not reported by cpp/futile-params
112-
(
113-
fdeEx.getNumberOfParameters() >= fc.getNumberOfArguments()
114-
or
115-
exists(Function f |
116-
f = fc.getTarget() and
117-
not exists(f.getBlock())
118-
or
119-
not hasZeroParamDeclTooMany(f)
120-
)
121-
) and
122-
// only report if not reported by cpp/too-few-arguments
123-
(
124-
fdeEx.getNumberOfParameters() <= fc.getNumberOfArguments()
125-
or
126-
exists(Function f |
127-
f.isVarargs() or
128-
f instanceof BuiltInFunction or
129-
not hasZeroParamDecl(f)
130-
)
131-
) and
132-
// only report if not reported by cpp/mistyped-function-arguments
133-
(
134-
not hasZeroParamDecl(fc.getTarget())
135-
or
136-
forall(ParameterDeclarationEntry pde |
137-
pde = fdeEx.getAParameterDeclarationEntry() and
138-
pde.getIndex() < fc.getNumberOfArguments()
139-
|
140-
argMayBeUsed(fc.getArgument(pde.getIndex()), pde)
141-
)
142-
)
143-
)
144-
}
145-
146-
predicate sameLocation(Location loc1, Location loc2) {
147-
loc1.getFile() = loc2.getFile() and
148-
loc1.getStartLine() = loc2.getStartLine() and
149-
loc1.getStartColumn() = loc2.getStartColumn()
150-
}
151-
15232
from FunctionDeclarationEntry fdeIm, FunctionCall fc
15333
where
15434
isCompiledAsC(fdeIm.getFile()) and
35+
not isFromMacroDefinition(fc) and
15536
fdeIm.isImplicit() and
15637
sameLocation(fdeIm.getLocation(), fc.getLocation()) and
157-
notAlreadyReported(fdeIm.getName(), fc)
38+
not mistypedFunctionArguments(fc, _, _) and
39+
not tooFewArguments(fc, _) and
40+
not tooManyArguments(fc, _)
15841
select fc, "Function call implicitly declares $@", fc, fc.toString()

0 commit comments

Comments
 (0)