Skip to content

Commit 099251a

Browse files
authored
Merge pull request github#10741 from hvitved/ruby/no-full-fast-tc
Ruby: Avoid computing full `fastTC` for `AstNode::getParent`
2 parents 1cf2db1 + 02192ac commit 099251a

File tree

3 files changed

+29
-15
lines changed

3 files changed

+29
-15
lines changed

ruby/ql/lib/codeql/ruby/ast/internal/Module.qll

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -486,12 +486,15 @@ private import ResolveImpl
486486
* methods evaluate the block in the context of some other module/class instead of
487487
* the enclosing one.
488488
*/
489-
private ModuleBase enclosingModule(AstNode node) { result = parent*(node).getParent() }
490-
491-
private AstNode parent(AstNode n) {
492-
result = n.getParent() and
493-
not result instanceof ModuleBase and
494-
not result instanceof Block
489+
private ModuleBase enclosingModule(AstNode node) {
490+
result = node.getParent()
491+
or
492+
exists(AstNode mid |
493+
result = enclosingModule(mid) and
494+
mid = node.getParent() and
495+
not mid instanceof ModuleBase and
496+
not mid instanceof Block
497+
)
495498
}
496499

497500
private Module getAncestors(Module m) {

ruby/ql/lib/codeql/ruby/ast/internal/Synthesis.qll

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,11 @@ class Synthesis extends TSynthesis {
118118
private class Desugared extends AstNode {
119119
Desugared() { this = any(AstNode sugar).getDesugared() }
120120

121-
AstNode getADescendant() { result = this.getAChild*() }
121+
AstNode getADescendant() {
122+
result = this
123+
or
124+
result = this.getADescendant().getAChild()
125+
}
122126
}
123127

124128
/**
@@ -132,7 +136,10 @@ int desugarLevel(AstNode n) { result = count(Desugared desugared | n = desugared
132136
* Holds if `n` appears in a context that is desugared. That is, a
133137
* transitive, reflexive parent of `n` is a desugared node.
134138
*/
135-
predicate isInDesugaredContext(AstNode n) { n = any(AstNode sugar).getDesugared().getAChild*() }
139+
predicate isInDesugaredContext(AstNode n) {
140+
n = any(AstNode sugar).getDesugared() or
141+
n = any(AstNode mid | isInDesugaredContext(mid)).getAChild()
142+
}
136143

137144
/**
138145
* Holds if `n` is a node that only exists as a result of desugaring some

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

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,19 +71,23 @@ private predicate completionIsValidForStmt(AstNode n, Completion c) {
7171
c = TReturnCompletion()
7272
}
7373

74-
/**
75-
* Holds if `c` happens in an exception-aware context, that is, it may be
76-
* `rescue`d or `ensure`d. In such cases, we assume that the target of `c`
77-
* may raise an exception (in addition to evaluating normally).
78-
*/
79-
private predicate mayRaise(Call c) {
80-
exists(Trees::BodyStmtTree bst | c = bst.getBodyChild(_, true).getAChild*() |
74+
private AstNode getARescuableBodyChild() {
75+
exists(Trees::BodyStmtTree bst | result = bst.getBodyChild(_, true) |
8176
exists(bst.getARescue())
8277
or
8378
exists(bst.getEnsure())
8479
)
80+
or
81+
result = getARescuableBodyChild().getAChild()
8582
}
8683

84+
/**
85+
* Holds if `c` happens in an exception-aware context, that is, it may be
86+
* `rescue`d or `ensure`d. In such cases, we assume that the target of `c`
87+
* may raise an exception (in addition to evaluating normally).
88+
*/
89+
private predicate mayRaise(Call c) { c = getARescuableBodyChild() }
90+
8791
/** A completion of a statement or an expression. */
8892
abstract class Completion extends TCompletion {
8993
private predicate isValidForSpecific(AstNode n) {

0 commit comments

Comments
 (0)