-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathIntegerPartial.qll
More file actions
99 lines (85 loc) · 2.22 KB
/
IntegerPartial.qll
File metadata and controls
99 lines (85 loc) · 2.22 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
/**
* Provides basic arithmetic operations that have no result if their result
* would overflow a 32-bit two's complement integer.
*/
/**
* Gets the value of the maximum representable integer.
*/
int maxValue() { result = 2147483647 }
/**
* Gets the value of the minimum representable integer.
*/
int minValue() { result = -2147483648 }
/**
* Holds if the value `f` is within the range of representable integers.
*/
bindingset[f]
pragma[inline]
private predicate isRepresentable(float f) { f >= minValue() and f <= maxValue() }
/**
* Returns `a + b`. If the addition overflows, there is no result.
*/
bindingset[a, b]
int add(int a, int b) {
isRepresentable(a.(float) + b.(float)) and
result = a + b
}
/**
* Returns `a - b`. If the subtraction overflows, there is no result.
*/
bindingset[a, b]
int sub(int a, int b) {
isRepresentable(a.(float) - b.(float)) and
result = a - b
}
/**
* Returns `a * b`. If the multiplication overflows, there is no result. If
* either input is not given, and the other input is non-zero, there is no
* result.
*/
bindingset[a, b]
int mul(int a, int b) {
a = 0 and
result = 0
or
b = 0 and
result = 0
or
isRepresentable(a.(float) * b.(float)) and
result = a * b
}
/**
* Returns `a / b`. If the division overflows, there is no result.
*/
bindingset[a, b]
int div(int a, int b) {
b != 0 and
(a != minValue() or b != -1) and
result = a / b
}
/** Returns `a == b`. */
bindingset[a, b]
int compareEQ(int a, int b) { if a = b then result = 1 else result = 0 }
/** Returns `a != b`. */
bindingset[a, b]
int compareNE(int a, int b) { if a != b then result = 1 else result = 0 }
/** Returns `a < b`. */
bindingset[a, b]
int compareLT(int a, int b) { if a < b then result = 1 else result = 0 }
/** Returns `a > b`. */
bindingset[a, b]
int compareGT(int a, int b) { if a > b then result = 1 else result = 0 }
/** Returns `a <= b`. */
bindingset[a, b]
int compareLE(int a, int b) { if a <= b then result = 1 else result = 0 }
/** Returns `a >= b`. */
bindingset[a, b]
int compareGE(int a, int b) { if a >= b then result = 1 else result = 0 }
/**
* Returns `-a`. If the negation would overflow, there is no result.
*/
bindingset[a]
int neg(int a) {
a != minValue() and
result = -a
}