mirror of
https://github.com/github/codeql.git
synced 2026-05-13 18:59:27 +02:00
54 lines
1.5 KiB
Plaintext
54 lines
1.5 KiB
Plaintext
/**
|
|
* @name Lossy function result cast
|
|
* @description Finds function calls whose result type is a floating point type, and which are casted to an integral type.
|
|
* Includes only expressions with implicit cast and excludes function calls to ceil, floor and round.
|
|
* @kind problem
|
|
* @id cpp/lossy-function-result-cast
|
|
* @problem.severity warning
|
|
* @precision medium
|
|
* @tags correctness
|
|
*/
|
|
|
|
import cpp
|
|
import semmle.code.cpp.dataflow.DataFlow
|
|
|
|
predicate whitelist(Function f) {
|
|
f.getName() =
|
|
[
|
|
"ceil", "ceilf", "ceill", "floor", "floorf", "floorl", "nearbyint", "nearbyintf",
|
|
"nearbyintl", "rint", "rintf", "rintl", "round", "roundf", "roundl", "trunc", "truncf",
|
|
"truncl"
|
|
] or
|
|
f.getName().matches("__builtin_%")
|
|
}
|
|
|
|
predicate whitelistPow(FunctionCall fc) {
|
|
fc.getTarget().getName() = ["pow", "powf", "powl"] and
|
|
exists(float value |
|
|
value = fc.getArgument(0).getValue().toFloat() and
|
|
(value.floor() - value).abs() < 0.001
|
|
)
|
|
}
|
|
|
|
predicate whiteListWrapped(FunctionCall fc) {
|
|
whitelist(fc.getTarget())
|
|
or
|
|
whitelistPow(fc)
|
|
or
|
|
exists(Expr e, ReturnStmt rs |
|
|
whiteListWrapped(e) and
|
|
DataFlow::localExprFlow(e, rs.getExpr()) and
|
|
fc.getTarget() = rs.getEnclosingFunction()
|
|
)
|
|
}
|
|
|
|
from FunctionCall c, FloatingPointType t1, IntegralType t2
|
|
where
|
|
t1 = c.getTarget().getType().getUnderlyingType() and
|
|
t2 = c.getActualType() and
|
|
c.hasImplicitConversion() and
|
|
not whiteListWrapped(c)
|
|
select c,
|
|
"Return value of type " + t1.toString() + " is implicitly converted to " + t2.toString() +
|
|
" here."
|