forked from github/codeql
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathConversions.qll
More file actions
140 lines (109 loc) · 3.62 KB
/
Conversions.qll
File metadata and controls
140 lines (109 loc) · 3.62 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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/**
* Provides support for conversion contexts, in which an expression is converted
* (implicitly or explicitly) to a different type.
*
* See the Java Language Specification, Section 5, for details.
*/
import java
import semmle.code.java.arithmetic.Overflow
/**
* A expression where an implicit conversion can occur.
*
* See the Java Language Specification, Section 5.
*/
abstract class ConversionSite extends Expr {
/**
* Gets the type that is converted to.
*/
abstract Type getConversionTarget();
/**
* Gets the type that is converted from.
*/
Type getConversionSource() { result = this.getType() }
/**
* Whether this conversion site actually induces a conversion.
*/
predicate isTrivial() { getConversionTarget() = getConversionSource() }
/**
* Whether this conversion is implicit.
*/
predicate isImplicit() { any() }
abstract string kind();
}
/**
* An assignment conversion. For example, `x += b` converts `b`
* to be of the type of `x`.
*
* See the Java Language Specification, Section 5.2.
*/
class AssignmentConversionContext extends ConversionSite {
Variable v;
AssignmentConversionContext() {
this = v.getAnAssignedValue()
or
exists(Assignment a | a.getDest() = v.getAnAccess() and this = a.getSource())
}
override Type getConversionTarget() { result = v.getType() }
override string kind() { result = "assignment context" }
}
/**
* An return conversion. For example, `return b` converts `b`
* to be of the return type of the enclosing callable.
*
* Note that the Java Language Specification handles these as
* assignment conversions (section 5.2), but for clarity we split them out here.
*/
class ReturnConversionSite extends ConversionSite {
ReturnStmt r;
ReturnConversionSite() { this = r.getResult() }
override Type getConversionTarget() { result = r.getEnclosingCallable().getReturnType() }
override string kind() { result = "return context" }
}
/**
* An invocation conversion. For example `f(b)` converts `b` to
* have the type of the corresponding parameter of `f`.
*
* See the Java Language Specification, Section 5.3.
*/
class InvocationConversionContext extends ConversionSite {
Call c;
int index;
InvocationConversionContext() { this = c.getArgument(index) }
override Type getConversionTarget() { result = c.getCallee().getParameter(index).getType() }
override string kind() { result = "invocation context" }
}
/**
* A string conversion. For example `a + b`, where `a` is a
* `String`, converts `b` to have type `String`.
*
* See the Java Language Specification, Section 5.4.
*/
class StringConversionContext extends ConversionSite {
AddExpr a;
StringConversionContext() {
a.getAnOperand() = this and
not this.getType() instanceof TypeString and
a.getAnOperand().getType() instanceof TypeString
}
override Type getConversionTarget() { result instanceof TypeString }
override string kind() { result = "string context" }
}
class CastConversionContext extends ConversionSite {
CastExpr c;
CastConversionContext() { this = c.getExpr() }
override Type getConversionTarget() { result = c.getType() }
override predicate isImplicit() { none() }
override string kind() { result = "cast context" }
}
/**
* A numeric conversion. For example, `a * b` converts `a` and
* `b` to have an appropriate numeric type.
*
* See the Java Language Specification, Section 5.4.
*/
class NumericConversionContext extends ConversionSite {
ArithExpr e;
NumericConversionContext() { this = e.getAnOperand() }
override Type getConversionTarget() { result = e.getType() }
override string kind() { result = "numeric context" }
}