Skip to content

Commit a4ea712

Browse files
committed
Ruby: CFG: make 'case' a PostOrder node
1 parent 3adc0b5 commit a4ea712

File tree

3 files changed

+114
-116
lines changed

3 files changed

+114
-116
lines changed

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

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,7 @@ abstract class Completion extends TCompletion {
107107
n = any(RescueModifierExpr parent).getBody() and
108108
this = [TSimpleCompletion().(TCompletion), TRaiseCompletion()]
109109
or
110-
(
111-
mayRaise(n)
112-
or
113-
n instanceof CaseMatch and not exists(n.(CaseExpr).getElseBranch())
114-
) and
110+
mayRaise(n) and
115111
(
116112
this = TRaiseCompletion()
117113
or

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

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -378,35 +378,18 @@ module Trees {
378378
override ControlFlowTree getChildElement(int i) { result = this.getArgument(i) }
379379
}
380380

381-
private class CaseTree extends PreOrderTree, CaseExpr, ASTInternal::TCaseExpr {
381+
private class CaseTree extends PostOrderTree, CaseExpr, ASTInternal::TCaseExpr {
382382
final override predicate propagatesAbnormal(AstNode child) {
383383
child = this.getValue() or child = this.getABranch()
384384
}
385385

386-
final override predicate last(AstNode last, Completion c) {
387-
last(this.getValue(), last, c) and not exists(this.getABranch())
388-
or
389-
last(this.getABranch().(WhenExpr).getBody(), last, c)
386+
final override predicate first(AstNode first) {
387+
first(this.getValue(), first)
390388
or
391-
exists(int i, ControlFlowTree lastBranch |
392-
lastBranch = this.getBranch(i) and
393-
not exists(this.getBranch(i + 1)) and
394-
last(lastBranch, last, c)
395-
)
389+
not exists(this.getValue()) and first(this.getBranch(0), first)
396390
}
397391

398392
final override predicate succ(AstNode pred, AstNode succ, Completion c) {
399-
exists(AstNode next |
400-
pred = this and
401-
first(next, succ) and
402-
c instanceof SimpleCompletion
403-
|
404-
next = this.getValue()
405-
or
406-
not exists(this.getValue()) and
407-
next = this.getBranch(0)
408-
)
409-
or
410393
last(this.getValue(), pred, c) and
411394
first(this.getBranch(0), succ) and
412395
c instanceof SimpleCompletion
@@ -416,17 +399,31 @@ module Trees {
416399
first(this.getBranch(i + 1), succ) and
417400
c.(ConditionalCompletion).getValue() = false
418401
)
402+
or
403+
succ = this and
404+
(
405+
last(this.getValue(), pred, c) and not exists(this.getABranch())
406+
or
407+
last(this.getABranch().(WhenExpr).getBody(), pred, c)
408+
or
409+
exists(int i, ControlFlowTree lastBranch |
410+
lastBranch = this.getBranch(i) and
411+
not exists(this.getBranch(i + 1)) and
412+
last(lastBranch, pred, c)
413+
)
414+
)
419415
}
420416
}
421417

422-
private class CaseMatchTree extends PreOrderTree, CaseExpr, ASTInternal::TCaseMatch {
418+
private class CaseMatchTree extends PostOrderTree, CaseExpr, ASTInternal::TCaseMatch {
423419
final override predicate propagatesAbnormal(AstNode child) {
424420
child = this.getValue() or child = this.getABranch()
425421
}
426422

423+
final override predicate first(AstNode first) { first(this.getValue(), first) }
424+
427425
final override predicate last(AstNode last, Completion c) {
428-
last(this.getABranch(), last, c) and
429-
not c.(MatchingCompletion).getValue() = false
426+
super.last(last, c)
430427
or
431428
not exists(this.getElseBranch()) and
432429
exists(MatchingCompletion lc, Expr lastBranch |
@@ -439,10 +436,6 @@ module Trees {
439436
}
440437

441438
final override predicate succ(AstNode pred, AstNode succ, Completion c) {
442-
pred = this and
443-
first(this.getValue(), succ) and
444-
c instanceof SimpleCompletion
445-
or
446439
last(this.getValue(), pred, c) and
447440
first(this.getBranch(0), succ) and
448441
c instanceof SimpleCompletion
@@ -452,6 +445,15 @@ module Trees {
452445
first(this.getBranch(i + 1), succ) and
453446
c.(MatchingCompletion).getValue() = false
454447
)
448+
or
449+
succ = this and
450+
(
451+
last(this.getABranch(), pred, c) and
452+
not c.(MatchingCompletion).getValue() = false
453+
or
454+
last(this.getElseBranch(), pred, c) and
455+
c instanceof NormalCompletion
456+
)
455457
}
456458
}
457459

0 commit comments

Comments
 (0)