Repository navigation
Expand file tree
/
Copy pathOverflow.qll
More file actions
129 lines (112 loc) · 3.68 KB
/
Copy pathOverflow.qll
File metadata and controls
129 lines (112 loc) · 3.68 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
overlay[local?]
module;
import java
/** A subclass of `PrimitiveType` with width-based ordering methods. */
class OrdPrimitiveType extends PrimitiveType {
predicate widerThan(OrdPrimitiveType that) { this.getWidthRank() > that.getWidthRank() }
predicate widerThanOrEqualTo(OrdPrimitiveType that) { this.getWidthRank() >= that.getWidthRank() }
OrdPrimitiveType maxType(OrdPrimitiveType that) {
this.widerThan(that) and result = this
or
not this.widerThan(that) and result = that
}
int getWidthRank() {
this.getName() = "byte" and result = 1
or
this.getName() = "short" and result = 2
or
this.getName() = "int" and result = 3
or
this.getName() = "long" and result = 4
or
this.getName() = "float" and result = 5
or
this.getName() = "double" and result = 6
}
float getMaxValue() {
this.getName() = "byte" and result = 127.0
or
this.getName() = "short" and result = 32767.0
or
this.getName() = "int" and result = 2147483647.0
or
// Long.MAX_VALUE is 9223372036854775807 but floating point only has 53 bits of precision.
this.getName() = "long" and result = 9223372036854776000.0
// don't try for floats and doubles
}
float getMinValue() {
this.getName() = "byte" and result = -128.0
or
this.getName() = "short" and result = -32768.0
or
this.getName() = "int" and result = -2147483648.0
or
// Long.MIN_VALUE is -9223372036854775808 but floating point only has 53 bits of precision.
this.getName() = "long" and result = -9223372036854776000.0
// don't try for floats and doubles
}
}
class NumType extends Type {
NumType() {
this instanceof PrimitiveType or
this instanceof BoxedType
}
/** Gets the width-ordered primitive type corresponding to this type. */
OrdPrimitiveType getOrdPrimitiveType() {
this instanceof PrimitiveType and result = this
or
this instanceof BoxedType and result = this.(BoxedType).getPrimitiveType()
}
predicate widerThan(NumType that) {
this.getOrdPrimitiveType().widerThan(that.getOrdPrimitiveType())
}
predicate widerThanOrEqualTo(NumType that) {
this.getOrdPrimitiveType().widerThanOrEqualTo(that.getOrdPrimitiveType())
}
int getWidthRank() { result = this.getOrdPrimitiveType().getWidthRank() }
}
class ArithExpr extends Expr {
ArithExpr() {
(
this instanceof UnaryAssignExpr or
this instanceof AddExpr or
this instanceof AssignAddExpr or
this instanceof MulExpr or
this instanceof AssignMulExpr or
this instanceof SubExpr or
this instanceof AssignSubExpr or
this instanceof DivExpr or
this instanceof AssignDivExpr
) and
forall(Expr e |
e = this.(BinaryExpr).getAnOperand() or
e = this.(UnaryAssignExpr).getOperand()
|
e.getType() instanceof NumType
)
}
OrdPrimitiveType getOrdPrimitiveType() {
exists(OrdPrimitiveType t1, OrdPrimitiveType t2 |
t1 = this.getLeftOperand().getType().(NumType).getOrdPrimitiveType() and
t2 = this.getRightOperand().getType().(NumType).getOrdPrimitiveType() and
result = t1.maxType(t2)
)
}
/**
* Gets the left-hand operand of a binary expression
* or the operand of a unary assignment expression.
*/
Expr getLeftOperand() {
result = this.(BinaryExpr).getLeftOperand() or
result = this.(UnaryAssignExpr).getOperand()
}
/**
* Gets the right-hand operand if this is a binary expression.
*/
Expr getRightOperand() { result = this.(BinaryExpr).getRightOperand() }
/** Gets an operand of this arithmetic expression. */
Expr getAnOperand() {
result = this.(BinaryExpr).getAnOperand() or
result = this.(UnaryAssignExpr).getOperand()
}
}