ruby: drop special handling of for-in loops in the CFG

This commit is contained in:
Alex Ford
2021-10-25 13:11:33 +01:00
committed by Tom Hvitved
parent ddfcfc9b67
commit e468434b82
3 changed files with 0 additions and 107 deletions

View File

@@ -132,7 +132,6 @@ private module Cached {
TFalseLiteral(Ruby::False g) or
TFloatLiteral(Ruby::Float g) { not any(Ruby::Rational r).getChild() = g } or
TForExpr(Ruby::For g) or
TForIn(Ruby::In g) or // TODO REMOVE
TForwardParameter(Ruby::ForwardParameter g) or
TForwardArgument(Ruby::ForwardArgument g) or
TGEExpr(Ruby::Binary g) { g instanceof @ruby_binary_rangleequal } or
@@ -389,7 +388,6 @@ private module Cached {
n = TFalseLiteral(result) or
n = TFloatLiteral(result) or
n = TForExpr(result) or
n = TForIn(result) or // TODO REMOVE
n = TForwardArgument(result) or
n = TForwardParameter(result) or
n = TGEExpr(result) or

View File

@@ -54,9 +54,6 @@ private predicate nestedEnsureCompletion(Completion outer, int nestLevel) {
pragma[noinline]
private predicate completionIsValidForStmt(AstNode n, Completion c) {
n = TForIn(_) and
c instanceof EmptinessCompletion
or
n instanceof BreakStmt and
c = TBreakCompletion()
or

View File

@@ -91,25 +91,6 @@ predicate succEntry(CfgScope::Range_ scope, AstNode first) { scope.entry(first)
pragma[nomagic]
predicate succExit(CfgScope::Range_ scope, AstNode last, Completion c) { scope.exit(last, c) }
// TODO: remove this class; it should be replaced with an implicit non AST node
private class ForIn extends AstNode, ASTInternal::TForIn {
final override string toString() { result = "In" }
}
// TODO: remove this class; it should be replaced with an implicit non AST node
private class ForRange extends ForExpr {
override AstNode getAChild(string pred) {
result = super.getAChild(pred)
or
pred = "<in>" and
result = this.getIn()
}
ForIn getIn() {
result = ASTInternal::TForIn(ASTInternal::toGenerated(this).(Ruby::For).getValue())
}
}
/** Defines the CFG by dispatch on the various AST types. */
module Trees {
private class AliasStmtTree extends StandardPreOrderTree, AliasStmt {
@@ -610,89 +591,6 @@ module Trees {
private class ForwardParameterTree extends LeafTree, ForwardParameter { }
private class ForInTree extends LeafTree, ForIn { }
/**
* Control flow of a for-in loop
*
* For example, this program fragment:
*
* ```rb
* for arg in args do
* puts arg
* end
* puts "done";
* ```
*
* has the following control flow graph:
*
* ```
* args
* |
* in------<-----
* / \ \
* / \ |
* / \ |
* / \ |
* empty non-empty |
* | \ |
* for \ |
* | arg |
* | | |
* puts "done" puts arg |
* \___/
* ```
*/
private class ForTree extends PostOrderTree, ForRange {
final override predicate propagatesAbnormal(AstNode child) {
child = this.getPattern() or child = this.getValue()
}
final override predicate first(AstNode first) { first(this.getValue(), first) }
/**
* for pattern in array do body end
* ```
* 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
first(this.getIn(), succ) and
c instanceof SimpleCompletion
or
last(this.getIn(), pred, c) and
first(this.getPattern(), succ) and
c.(EmptinessCompletion).getValue() = false
or
last(this.getPattern(), pred, c) and
first(this.getBody(), succ) and
c instanceof NormalCompletion
or
last(this.getBody(), pred, c) 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())
)
}
}
private class GlobalVariableTree extends LeafTree, GlobalVariableAccess { }
private class HashLiteralTree extends StandardPostOrderTree, HashLiteral {