Skip to content

Commit 6473977

Browse files
authored
Merge pull request #10336 from hvitved/ruby/call-graph-rework
Ruby: Rework call graph implementation
2 parents 90f24d3 + bb08e6f commit 6473977

File tree

16 files changed

+2431
-984
lines changed

16 files changed

+2431
-984
lines changed

ruby/ql/consistency-queries/DataFlowConsistency.ql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import codeql.ruby.AST
12
import codeql.ruby.DataFlow::DataFlow
23
import codeql.ruby.dataflow.internal.DataFlowPrivate
34
import codeql.ruby.dataflow.internal.DataFlowImplConsistency::Consistency
@@ -11,5 +12,7 @@ private class MyConsistencyConfiguration extends ConsistencyConfiguration {
1112
n instanceof SummaryNode
1213
or
1314
n instanceof SynthHashSplatArgumentNode
15+
or
16+
not isNonConstantExpr(n.asExpr())
1417
}
1518
}

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

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,7 @@ private module Cached {
137137
}
138138

139139
cached
140-
Method lookupMethod(Module m, string name) {
141-
// The syntax_suggest library redefines Kernel.require/require_relative.
142-
// Somehow this causes performance issues on ruby/ruby. As a workaround
143-
// we exclude 'require' and 'require_relative'.
144-
// TODO: find the actual cause of the slowdown and fix things properly.
145-
not name = ["require", "require_relative"] and
146-
TMethod(result) = lookupMethodOrConst(m, name)
147-
}
140+
Method lookupMethod(Module m, string name) { TMethod(result) = lookupMethodOrConst(m, name) }
148141

149142
cached
150143
Expr lookupConst(Module m, string name) {

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -311,13 +311,13 @@ private module Cached {
311311
}
312312

313313
cached
314-
predicate immediatelyControls(ConditionBlock cb, BasicBlock succ, BooleanSuccessor s) {
314+
predicate immediatelyControls(ConditionBlock cb, BasicBlock succ, ConditionalSuccessor s) {
315315
succ = cb.getASuccessor(s) and
316316
forall(BasicBlock pred | pred = succ.getAPredecessor() and pred != cb | succ.dominates(pred))
317317
}
318318

319319
cached
320-
predicate controls(ConditionBlock cb, BasicBlock controlled, BooleanSuccessor s) {
320+
predicate controls(ConditionBlock cb, BasicBlock controlled, ConditionalSuccessor s) {
321321
exists(BasicBlock succ | cb.immediatelyControls(succ, s) | succ.dominates(controlled))
322322
}
323323
}
@@ -406,7 +406,7 @@ class ConditionBlock extends BasicBlock {
406406
* successor of this block, and `succ` can only be reached from
407407
* the callable entry point by going via the `s` edge out of this basic block.
408408
*/
409-
predicate immediatelyControls(BasicBlock succ, BooleanSuccessor s) {
409+
predicate immediatelyControls(BasicBlock succ, ConditionalSuccessor s) {
410410
immediatelyControls(this, succ, s)
411411
}
412412

@@ -415,5 +415,7 @@ class ConditionBlock extends BasicBlock {
415415
* conditional value `s`. That is, `controlled` can only be reached from
416416
* the callable entry point by going via the `s` edge out of this basic block.
417417
*/
418-
predicate controls(BasicBlock controlled, BooleanSuccessor s) { controls(this, controlled, s) }
418+
predicate controls(BasicBlock controlled, ConditionalSuccessor s) {
419+
controls(this, controlled, s)
420+
}
419421
}

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ module ExprNodes {
433433
}
434434

435435
private class WhenClauseChildMapping extends NonExprChildMapping, WhenClause {
436-
override predicate relevantChild(AstNode e) { e = this.getBody() }
436+
override predicate relevantChild(AstNode e) { e = [this.getBody(), this.getAPattern()] }
437437
}
438438

439439
/** A control-flow node that wraps a `WhenClause` AST expression. */
@@ -444,6 +444,9 @@ module ExprNodes {
444444

445445
/** Gets the body of this `when`-clause. */
446446
final ExprCfgNode getBody() { e.hasCfgChild(e.getBody(), this, result) }
447+
448+
/** Gets the `i`th pattern this `when`-clause. */
449+
final ExprCfgNode getPattern(int i) { e.hasCfgChild(e.getPattern(i), this, result) }
447450
}
448451

449452
/** A control-flow node that wraps a `CasePattern`. */

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class CfgNode extends TCfgNode {
4444
final File getFile() { result = this.getLocation().getFile() }
4545

4646
/** Holds if this control flow node has conditional successors. */
47-
final predicate isCondition() { exists(this.getASuccessor(any(BooleanSuccessor bs))) }
47+
final predicate isCondition() { exists(this.getASuccessor(any(ConditionalSuccessor bs))) }
4848

4949
/** Gets the scope of this node. */
5050
final CfgScope getScope() { result = getNodeCfgScope(this) }

0 commit comments

Comments
 (0)