mirror of
https://github.com/github/codeql.git
synced 2026-02-20 08:53:49 +01:00
Merge pull request #116 from github/aibaars/cfg-loop-post-order
CFG: make loop expressions post order
This commit is contained in:
@@ -54,6 +54,9 @@ private predicate nestedEnsureCompletion(Completion outer, int nestLevel) {
|
||||
|
||||
pragma[noinline]
|
||||
private predicate completionIsValidForStmt(AstNode n, Completion c) {
|
||||
n instanceof In and
|
||||
c instanceof EmptinessCompletion
|
||||
or
|
||||
n instanceof Break and
|
||||
c = TBreakCompletion()
|
||||
or
|
||||
|
||||
@@ -339,7 +339,7 @@ private class LeftToRightPostOrderTree extends StandardPostOrderTree, LeftToRigh
|
||||
}
|
||||
|
||||
private class LeftToRightPreOrderNodes =
|
||||
@alias or @block_parameters or @class or @do or @else or @ensure or @in or @lambda_parameters or
|
||||
@alias or @block_parameters or @class or @do or @else or @ensure or @lambda_parameters or
|
||||
@method_parameters or @pattern or @program or @then or @undef or @yield;
|
||||
|
||||
private class LeftToRightPreOrderTree extends StandardPreOrderTree, LeftToRightPreOrderNodes {
|
||||
@@ -347,7 +347,6 @@ private class LeftToRightPreOrderTree extends StandardPreOrderTree, LeftToRightP
|
||||
this instanceof BlockParameters or
|
||||
this instanceof Do or
|
||||
this instanceof Else or
|
||||
this instanceof In or
|
||||
this instanceof LambdaParameters or
|
||||
this instanceof MethodParameters or
|
||||
this instanceof Pattern or
|
||||
@@ -593,66 +592,71 @@ module Trees {
|
||||
* ```
|
||||
* args
|
||||
* |
|
||||
* for------<-----
|
||||
* in------<-----
|
||||
* / \ \
|
||||
* / \ |
|
||||
* / \ |
|
||||
* / \ |
|
||||
* empty non-empty |
|
||||
* | \ |
|
||||
* puts "done" \ |
|
||||
* arg |
|
||||
* | |
|
||||
* puts arg |
|
||||
* for \ |
|
||||
* | arg |
|
||||
* | | |
|
||||
* puts "done" puts arg |
|
||||
* \___/
|
||||
* ```
|
||||
*/
|
||||
private class ForTree extends ControlFlowTree, For {
|
||||
private class ForTree extends PostOrderTree, For {
|
||||
final override predicate propagatesAbnormal(AstNode child) {
|
||||
child = this.getPattern() or child = this.getValue()
|
||||
child = this.getPattern() or child = this.getArray()
|
||||
}
|
||||
|
||||
final override predicate first(AstNode node) { node = this.getValue() }
|
||||
final override predicate first(AstNode first) { first(this.getArray(), first) }
|
||||
|
||||
final override predicate last(AstNode last, Completion c) {
|
||||
last = this and
|
||||
c.(EmptinessCompletion).getValue() = true
|
||||
or
|
||||
last(this.getBody(), last, c) and
|
||||
not c.continuesLoop() and
|
||||
not c instanceof BreakCompletion and
|
||||
not c instanceof RedoCompletion
|
||||
or
|
||||
last(this.getBody(), last, c.(NestedBreakCompletion).getAnInnerCompatibleCompletion())
|
||||
}
|
||||
private In getIn() { result = this.getValue() }
|
||||
|
||||
private UnderscoreArg getArray() { result = this.getValue().getChild() }
|
||||
|
||||
/**
|
||||
* for pattern in value do body end
|
||||
* for pattern in array do body end
|
||||
* ```
|
||||
* value +-> for +--[non empty]--> pattern -> body -> for
|
||||
* |--[empty]--> exit
|
||||
* array +-> in +--[non empty]--> pattern -> body -> in
|
||||
* |--[empty]--> for
|
||||
* ```
|
||||
*/
|
||||
final override predicate succ(AstNode pred, AstNode succ, Completion c) {
|
||||
last(this.getValue(), pred, c) and
|
||||
succ = this and
|
||||
last(this.getArray(), pred, c) and
|
||||
first(this.getIn(), succ) and
|
||||
c instanceof SimpleCompletion
|
||||
or
|
||||
pred = this and
|
||||
last(this.getIn(), pred, c) and
|
||||
first(this.getPattern(), succ) and
|
||||
c.(EmptinessCompletion).getValue() = false
|
||||
or
|
||||
first(this.getBody(), succ) and
|
||||
last(this.getPattern(), pred, c) and
|
||||
first(this.getBody(), succ) and
|
||||
c instanceof NormalCompletion
|
||||
or
|
||||
last(this.getBody(), pred, c) and
|
||||
succ = this and
|
||||
first(this.getIn(), succ) and
|
||||
c.continuesLoop()
|
||||
or
|
||||
last(this.getBody(), pred, c) and
|
||||
first(this.getBody(), succ) and
|
||||
c instanceof RedoCompletion
|
||||
or
|
||||
succ = this and
|
||||
(
|
||||
last(this.getIn(), pred, c) and
|
||||
c.(EmptinessCompletion).getValue() = true
|
||||
or
|
||||
last(this.getBody(), pred, c) and
|
||||
not c.continuesLoop() and
|
||||
not c instanceof BreakCompletion and
|
||||
not c instanceof RedoCompletion
|
||||
or
|
||||
last(this.getBody(), pred, c.(NestedBreakCompletion).getAnInnerCompatibleCompletion())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -712,6 +716,8 @@ module Trees {
|
||||
}
|
||||
}
|
||||
|
||||
private class InTree extends LeafTree, In { }
|
||||
|
||||
private class InstanceVariableTree extends LeafTree, InstanceVariable { }
|
||||
|
||||
private class IntegerTree extends LeafTree, Integer { }
|
||||
@@ -1224,26 +1230,12 @@ module Trees {
|
||||
}
|
||||
}
|
||||
|
||||
private class ConditionalLoopTree extends PreOrderTree, ConditionalLoopAstNode {
|
||||
private class ConditionalLoopTree extends PostOrderTree, ConditionalLoopAstNode {
|
||||
final override predicate propagatesAbnormal(AstNode child) { child = this.getConditionNode() }
|
||||
|
||||
final override predicate last(AstNode last, Completion c) {
|
||||
last(this.getConditionNode(), last, c) and
|
||||
this.endLoop(c)
|
||||
or
|
||||
last(this.getBodyNode(), last, c) and
|
||||
not c.continuesLoop() and
|
||||
not c instanceof BreakCompletion and
|
||||
not c instanceof RedoCompletion
|
||||
or
|
||||
last(this.getBodyNode(), last, c.(NestedBreakCompletion).getAnInnerCompatibleCompletion())
|
||||
}
|
||||
final override predicate first(AstNode first) { first(this.getConditionNode(), first) }
|
||||
|
||||
final override predicate succ(AstNode pred, AstNode succ, Completion c) {
|
||||
pred = this and
|
||||
first(this.getConditionNode(), succ) and
|
||||
c instanceof SimpleCompletion
|
||||
or
|
||||
last(this.getConditionNode(), pred, c) and
|
||||
this.continueLoop(c) and
|
||||
first(this.getBodyNode(), succ)
|
||||
@@ -1255,6 +1247,19 @@ module Trees {
|
||||
last(this.getBodyNode(), pred, c) and
|
||||
first(this.getBodyNode(), succ) and
|
||||
c instanceof RedoCompletion
|
||||
or
|
||||
succ = this and
|
||||
(
|
||||
last(this.getConditionNode(), pred, c) and
|
||||
this.endLoop(c)
|
||||
or
|
||||
last(this.getBodyNode(), pred, c) and
|
||||
not c.continuesLoop() and
|
||||
not c instanceof BreakCompletion and
|
||||
not c instanceof RedoCompletion
|
||||
or
|
||||
last(this.getBodyNode(), pred, c.(NestedBreakCompletion).getAnInnerCompatibleCompletion())
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user