-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathLossyFunctionResultCast.ql
More file actions
52 lines (47 loc) · 1.56 KB
/
LossyFunctionResultCast.ql
File metadata and controls
52 lines (47 loc) · 1.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/**
* @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
pragma[only_bind_into](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() + "."