Skip to content

Commit ce85279

Browse files
committed
Ruby: Use shared SuccessorType.
1 parent a8c1b15 commit ce85279

File tree

11 files changed

+28
-287
lines changed

11 files changed

+28
-287
lines changed

ruby/ql/consistency-queries/DataFlowConsistency.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ private module Input implements InputSig<Location, RubyDataFlow> {
2828
exists(CfgNodes::ExprCfgNode n |
2929
arg.argumentOf(call, _) and
3030
n = call.asCall() and
31-
arg.asExpr().getASuccessor(any(SuccessorTypes::ConditionalSuccessor c)).getASuccessor*() = n and
31+
arg.asExpr().getASuccessor(any(ConditionalSuccessor c)).getASuccessor*() = n and
3232
n.getASplit() instanceof Split::ConditionalCompletionSplit
3333
)
3434
}

ruby/ql/lib/codeql/ruby/controlflow/BasicBlocks.qll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ private import codeql.ruby.ast.internal.TreeSitter
88
private import codeql.ruby.controlflow.ControlFlowGraph
99
private import internal.ControlFlowGraphImpl as CfgImpl
1010
private import CfgNodes
11-
private import SuccessorTypes
1211
private import CfgImpl::BasicBlocks as BasicBlocksImpl
1312

1413
/**

ruby/ql/lib/codeql/ruby/controlflow/ControlFlowGraph.qll

Lines changed: 1 addition & 236 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
overlay[local]
33
module;
44

5+
import codeql.controlflow.SuccessorType
56
private import codeql.ruby.AST
67
private import codeql.ruby.controlflow.BasicBlocks
7-
private import SuccessorTypes
88
private import internal.ControlFlowGraphImpl as CfgImpl
99
private import internal.Splitting as Splitting
1010
private import internal.Completion
@@ -59,241 +59,6 @@ class CfgNode extends CfgImpl::Node {
5959
BasicBlock getBasicBlock() { result.getANode() = this }
6060
}
6161

62-
/** The type of a control flow successor. */
63-
class SuccessorType extends CfgImpl::TSuccessorType {
64-
/** Gets a textual representation of successor type. */
65-
string toString() { none() }
66-
}
67-
68-
/** Provides different types of control flow successor types. */
69-
module SuccessorTypes {
70-
/** A normal control flow successor. */
71-
class NormalSuccessor extends SuccessorType, CfgImpl::TSuccessorSuccessor {
72-
final override string toString() { result = "successor" }
73-
}
74-
75-
/**
76-
* A conditional control flow successor. Either a Boolean successor (`BooleanSuccessor`)
77-
* or a matching successor (`MatchingSuccessor`)
78-
*/
79-
class ConditionalSuccessor extends SuccessorType {
80-
boolean value;
81-
82-
ConditionalSuccessor() {
83-
this = CfgImpl::TBooleanSuccessor(value) or
84-
this = CfgImpl::TMatchingSuccessor(value)
85-
}
86-
87-
/** Gets the Boolean value of this successor. */
88-
final boolean getValue() { result = value }
89-
90-
override string toString() { result = this.getValue().toString() }
91-
}
92-
93-
/**
94-
* A Boolean control flow successor.
95-
*
96-
* For example, in
97-
*
98-
* ```rb
99-
* if x >= 0
100-
* puts "positive"
101-
* else
102-
* puts "negative"
103-
* end
104-
* ```
105-
*
106-
* `x >= 0` has both a `true` successor and a `false` successor.
107-
*/
108-
class BooleanSuccessor extends ConditionalSuccessor, CfgImpl::TBooleanSuccessor { }
109-
110-
/**
111-
* A matching control flow successor.
112-
*
113-
* For example, this program fragment:
114-
*
115-
* ```rb
116-
* case x
117-
* when 1 then puts "one"
118-
* else puts "not one"
119-
* end
120-
* ```
121-
*
122-
* has a control flow graph containing matching successors:
123-
*
124-
* ```
125-
* x
126-
* |
127-
* 1
128-
* / \
129-
* / \
130-
* / \
131-
* / \
132-
* match non-match
133-
* | |
134-
* puts "one" puts "not one"
135-
* ```
136-
*/
137-
class MatchingSuccessor extends ConditionalSuccessor, CfgImpl::TMatchingSuccessor {
138-
override string toString() { if value = true then result = "match" else result = "no-match" }
139-
}
140-
141-
/**
142-
* A `return` control flow successor.
143-
*
144-
* Example:
145-
*
146-
* ```rb
147-
* def sum(x,y)
148-
* return x + y
149-
* end
150-
* ```
151-
*
152-
* The exit node of `sum` is a `return` successor of the `return x + y`
153-
* statement.
154-
*/
155-
class ReturnSuccessor extends SuccessorType, CfgImpl::TReturnSuccessor {
156-
final override string toString() { result = "return" }
157-
}
158-
159-
/**
160-
* A `break` control flow successor.
161-
*
162-
* Example:
163-
*
164-
* ```rb
165-
* def m
166-
* while x >= 0
167-
* x -= 1
168-
* if num > 100
169-
* break
170-
* end
171-
* end
172-
* puts "done"
173-
* end
174-
* ```
175-
*
176-
* The node `puts "done"` is `break` successor of the node `break`.
177-
*/
178-
class BreakSuccessor extends SuccessorType, CfgImpl::TBreakSuccessor {
179-
final override string toString() { result = "break" }
180-
}
181-
182-
/**
183-
* A `next` control flow successor.
184-
*
185-
* Example:
186-
*
187-
* ```rb
188-
* def m
189-
* while x >= 0
190-
* x -= 1
191-
* if num > 100
192-
* next
193-
* end
194-
* end
195-
* puts "done"
196-
* end
197-
* ```
198-
*
199-
* The node `x >= 0` is `next` successor of the node `next`.
200-
*/
201-
class NextSuccessor extends SuccessorType, CfgImpl::TNextSuccessor {
202-
final override string toString() { result = "next" }
203-
}
204-
205-
/**
206-
* A `redo` control flow successor.
207-
*
208-
* Example:
209-
*
210-
* Example:
211-
*
212-
* ```rb
213-
* def m
214-
* while x >= 0
215-
* x -= 1
216-
* if num > 100
217-
* redo
218-
* end
219-
* end
220-
* puts "done"
221-
* end
222-
* ```
223-
*
224-
* The node `x -= 1` is `redo` successor of the node `redo`.
225-
*/
226-
class RedoSuccessor extends SuccessorType, CfgImpl::TRedoSuccessor {
227-
final override string toString() { result = "redo" }
228-
}
229-
230-
/**
231-
* A `retry` control flow successor.
232-
*
233-
* Example:
234-
*
235-
* Example:
236-
*
237-
* ```rb
238-
* def m
239-
* begin
240-
* puts "Retry"
241-
* raise
242-
* rescue
243-
* retry
244-
* end
245-
* end
246-
* ```
247-
*
248-
* The node `puts "Retry"` is `retry` successor of the node `retry`.
249-
*/
250-
class RetrySuccessor extends SuccessorType, CfgImpl::TRetrySuccessor {
251-
final override string toString() { result = "retry" }
252-
}
253-
254-
/**
255-
* An exceptional control flow successor.
256-
*
257-
* Example:
258-
*
259-
* ```rb
260-
* def m x
261-
* if x > 2
262-
* raise "x > 2"
263-
* end
264-
* puts "x <= 2"
265-
* end
266-
* ```
267-
*
268-
* The exit node of `m` is an exceptional successor of the node
269-
* `raise "x > 2"`.
270-
*/
271-
class RaiseSuccessor extends SuccessorType, CfgImpl::TRaiseSuccessor {
272-
final override string toString() { result = "raise" }
273-
}
274-
275-
/**
276-
* An exit control flow successor.
277-
*
278-
* Example:
279-
*
280-
* ```rb
281-
* def m x
282-
* if x > 2
283-
* exit 1
284-
* end
285-
* puts "x <= 2"
286-
* end
287-
* ```
288-
*
289-
* The exit node of `m` is an exit successor of the node
290-
* `exit 1`.
291-
*/
292-
class ExitSuccessor extends SuccessorType, CfgImpl::TExitSuccessor {
293-
final override string toString() { result = "exit" }
294-
}
295-
}
296-
29762
class Split = Splitting::Split;
29863

29964
/** Provides different kinds of control flow graph splittings. */

ruby/ql/lib/codeql/ruby/controlflow/internal/Completion.qll

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ private import codeql.ruby.ast.internal.Control
1212
private import codeql.ruby.controlflow.ControlFlowGraph
1313
private import ControlFlowGraphImpl as CfgImpl
1414
private import NonReturning
15-
private import SuccessorTypes
1615

1716
private newtype TCompletion =
1817
TSimpleCompletion() or
@@ -267,7 +266,7 @@ abstract private class NonNestedNormalCompletion extends NormalCompletion { }
267266

268267
/** A simple (normal) completion. */
269268
class SimpleCompletion extends NonNestedNormalCompletion, TSimpleCompletion {
270-
override NormalSuccessor getAMatchingSuccessorType() { any() }
269+
override DirectSuccessor getAMatchingSuccessorType() { any() }
271270

272271
override string toString() { result = "simple" }
273272
}
@@ -359,7 +358,7 @@ class BreakCompletion extends Completion {
359358
this = TNestedCompletion(_, TBreakCompletion(), _)
360359
}
361360

362-
override BreakSuccessor getAMatchingSuccessorType() { any() }
361+
override JumpSuccessor getAMatchingSuccessorType() { any() }
363362

364363
override string toString() {
365364
// `NestedCompletion` defines `toString()` for the other case
@@ -377,7 +376,7 @@ class NextCompletion extends Completion {
377376
this = TNestedCompletion(_, TNextCompletion(), _)
378377
}
379378

380-
override NextSuccessor getAMatchingSuccessorType() { any() }
379+
override JumpSuccessor getAMatchingSuccessorType() { any() }
381380

382381
override string toString() {
383382
// `NestedCompletion` defines `toString()` for the other case
@@ -395,7 +394,7 @@ class RedoCompletion extends Completion {
395394
this = TNestedCompletion(_, TRedoCompletion(), _)
396395
}
397396

398-
override RedoSuccessor getAMatchingSuccessorType() { any() }
397+
override JumpSuccessor getAMatchingSuccessorType() { any() }
399398

400399
override string toString() {
401400
// `NestedCompletion` defines `toString()` for the other case
@@ -413,7 +412,7 @@ class RetryCompletion extends Completion {
413412
this = TNestedCompletion(_, TRetryCompletion(), _)
414413
}
415414

416-
override RetrySuccessor getAMatchingSuccessorType() { any() }
415+
override JumpSuccessor getAMatchingSuccessorType() { any() }
417416

418417
override string toString() {
419418
// `NestedCompletion` defines `toString()` for the other case
@@ -431,7 +430,7 @@ class RaiseCompletion extends Completion {
431430
this = TNestedCompletion(_, TRaiseCompletion(), _)
432431
}
433432

434-
override RaiseSuccessor getAMatchingSuccessorType() { any() }
433+
override ExceptionSuccessor getAMatchingSuccessorType() { any() }
435434

436435
override string toString() {
437436
// `NestedCompletion` defines `toString()` for the other case
@@ -512,7 +511,7 @@ class NestedBreakCompletion extends NormalCompletion, NestedCompletion {
512511

513512
override SuccessorType getAMatchingSuccessorType() {
514513
outer instanceof SimpleCompletion and
515-
result instanceof BreakSuccessor
514+
result instanceof JumpSuccessor
516515
or
517516
result = outer.(ConditionalCompletion).getAMatchingSuccessorType()
518517
}

ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,13 @@ private module CfgInput implements CfgShared::InputSig<Location> {
5050

5151
SuccessorType getAMatchingSuccessorType(Completion c) { result = c.getAMatchingSuccessorType() }
5252

53-
predicate successorTypeIsSimple(SuccessorType t) {
54-
t instanceof Cfg::SuccessorTypes::NormalSuccessor
55-
}
53+
predicate successorTypeIsSimple(SuccessorType t) { t instanceof Cfg::DirectSuccessor }
5654

57-
predicate successorTypeIsCondition(SuccessorType t) {
58-
t instanceof Cfg::SuccessorTypes::ConditionalSuccessor
59-
}
55+
predicate successorTypeIsCondition(SuccessorType t) { t instanceof Cfg::ConditionalSuccessor }
6056

6157
predicate isAbnormalExitType(SuccessorType t) {
62-
t instanceof Cfg::SuccessorTypes::RaiseSuccessor or
63-
t instanceof Cfg::SuccessorTypes::ExitSuccessor
58+
t instanceof Cfg::ExceptionSuccessor or
59+
t instanceof Cfg::ExitSuccessor
6460
}
6561

6662
private predicate id(Ruby::AstNode node1, Ruby::AstNode node2) { node1 = node2 }
@@ -1528,21 +1524,3 @@ CfgScope getCfgScope(AstNode n) {
15281524
pragma[only_bind_into](result) = getCfgScopeImpl(n0)
15291525
)
15301526
}
1531-
1532-
cached
1533-
private module Cached {
1534-
cached
1535-
newtype TSuccessorType =
1536-
TSuccessorSuccessor() or
1537-
TBooleanSuccessor(boolean b) { b in [false, true] } or
1538-
TMatchingSuccessor(boolean isMatch) { isMatch in [false, true] } or
1539-
TReturnSuccessor() or
1540-
TBreakSuccessor() or
1541-
TNextSuccessor() or
1542-
TRedoSuccessor() or
1543-
TRetrySuccessor() or
1544-
TRaiseSuccessor() or // TODO: Add exception type?
1545-
TExitSuccessor()
1546-
}
1547-
1548-
import Cached

ruby/ql/lib/codeql/ruby/controlflow/internal/Guards.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ private import codeql.ruby.CFG
66
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
77
pragma[nomagic]
88
predicate guardControlsBlock(CfgNodes::AstCfgNode guard, BasicBlock bb, boolean branch) {
9-
exists(ConditionBlock conditionBlock, SuccessorTypes::ConditionalSuccessor s |
9+
exists(ConditionBlock conditionBlock, ConditionalSuccessor s |
1010
guard = conditionBlock.getLastNode() and
1111
s.getValue() = branch and
1212
conditionBlock.edgeDominates(bb, s)

0 commit comments

Comments
 (0)