-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathEdgeKind.qll
More file actions
139 lines (120 loc) · 3.9 KB
/
EdgeKind.qll
File metadata and controls
139 lines (120 loc) · 3.9 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
/**
* Provides classes that specify the conditions under which control flows along a given edge.
*/
private import internal.EdgeKindInternal
private newtype TEdgeKind =
TGotoEdge() or // Single successor (including fall-through)
TTrueEdge() or // 'true' edge of conditional branch
TFalseEdge() or // 'false' edge of conditional branch
TExceptionEdge() or // Thrown exception
TDefaultEdge() or // 'default' label of switch
TCaseEdge(string minValue, string maxValue) {
// Case label of switch
Language::hasCaseEdge(minValue, maxValue)
}
/**
* Represents the kind of an edge in the IR control flow graph. Each
* `Instruction` or `IRBlock` has at most one successor of any single
* `EdgeKind`.
*/
abstract class EdgeKind extends TEdgeKind {
/** Gets a textual representation of this edge kind. */
abstract string toString();
}
/**
* A "goto" edge, representing the unconditional successor of an `Instruction`
* or `IRBlock`.
*/
class GotoEdge extends EdgeKind, TGotoEdge {
final override string toString() { result = "Goto" }
}
/**
* A "true" edge, representing the successor of a conditional branch when the
* condition is non-zero.
*/
class TrueEdge extends EdgeKind, TTrueEdge {
final override string toString() { result = "True" }
}
/**
* A "false" edge, representing the successor of a conditional branch when the
* condition is zero.
*/
class FalseEdge extends EdgeKind, TFalseEdge {
final override string toString() { result = "False" }
}
/**
* An "exception" edge, representing the successor of an instruction when that
* instruction's evaluation throws an exception.
*/
class ExceptionEdge extends EdgeKind, TExceptionEdge {
final override string toString() { result = "Exception" }
}
/**
* A "default" edge, representing the successor of a `Switch` instruction when
* none of the case values matches the condition value.
*/
class DefaultEdge extends EdgeKind, TDefaultEdge {
final override string toString() { result = "Default" }
}
/**
* A "case" edge, representing the successor of a `Switch` instruction when the
* the condition value matches a correponding `case` label.
*/
class CaseEdge extends EdgeKind, TCaseEdge {
string minValue;
string maxValue;
CaseEdge() { this = TCaseEdge(minValue, maxValue) }
final override string toString() {
if minValue = maxValue
then result = "Case[" + minValue + "]"
else result = "Case[" + minValue + ".." + maxValue + "]"
}
/**
* Gets the smallest value of the switch expression for which control will flow along this edge.
*/
final string getMinValue() { result = minValue }
/**
* Gets the largest value of the switch expression for which control will flow along this edge.
*/
final string getMaxValue() { result = maxValue }
}
/**
* Predicates to access the single instance of each `EdgeKind` class.
*/
module EdgeKind {
/**
* Gets the single instance of the `GotoEdge` class.
*/
GotoEdge gotoEdge() { result = TGotoEdge() }
/**
* Gets the single instance of the `TrueEdge` class.
*/
TrueEdge trueEdge() { result = TTrueEdge() }
/**
* Gets the single instance of the `FalseEdge` class.
*/
FalseEdge falseEdge() { result = TFalseEdge() }
/**
* Gets the single instance of the `ExceptionEdge` class.
*/
ExceptionEdge exceptionEdge() { result = TExceptionEdge() }
/**
* Gets the single instance of the `DefaultEdge` class.
*/
DefaultEdge defaultEdge() { result = TDefaultEdge() }
/**
* Gets the `CaseEdge` representing a `case` label with the specified lower and upper bounds.
* For example:
* ```
* switch (x) {
* case 1: // Edge kind is `caseEdge("1", "1")`
* return x;
* case 2...8: // Edge kind is `caseEdge("2", "8")`
* return x - 1;
* default: // Edge kind is `defaultEdge()`
* return 0;
* }
* ```
*/
CaseEdge caseEdge(string minValue, string maxValue) { result = TCaseEdge(minValue, maxValue) }
}