mirror of
https://github.com/github/codeql.git
synced 2026-04-26 09:15:12 +02:00
[CPP-340] Add more test case; exclude K&R definitions of functions when looking
up ()-declarations; refactor QL code.
This commit is contained in:
@@ -14,23 +14,26 @@
|
||||
|
||||
import cpp
|
||||
|
||||
predicate arithTypesMatch(Type arg, Type parm) {
|
||||
arg instanceof ArithmeticType and
|
||||
parm instanceof ArithmeticType and
|
||||
arg.getSize() = parm.getSize() and
|
||||
(
|
||||
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
|
||||
// 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
|
||||
)
|
||||
arithTypesMatch(arg, parm)
|
||||
or
|
||||
// pointers to void are ok
|
||||
// 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
|
||||
not f.isVarargs() and
|
||||
p.getIndex() < fc.getNumberOfArguments() and
|
||||
hasZeroParamDecl(f) and
|
||||
isCompiledAsC(f) and
|
||||
not f.isVarargs() and
|
||||
not f instanceof BuiltInFunction and
|
||||
p.getIndex() < fc.getNumberOfArguments() 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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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() |
|
||||
|
||||
Reference in New Issue
Block a user