[CPP-340] Make the query more strict (again).

This commit is contained in:
Ziemowit Laski
2019-04-10 09:55:37 -07:00
parent ef54b012e0
commit dc7497835e
5 changed files with 72 additions and 36 deletions

View File

@@ -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()