Skip to content

Commit 6c16b8a

Browse files
committed
Ruby: Unmerge SSA and data flow stages
1 parent e69b99e commit 6c16b8a

File tree

2 files changed

+42
-29
lines changed

2 files changed

+42
-29
lines changed

ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,15 @@ SsaImpl::DefinitionExt getParameterDef(NamedParameter p) {
8383

8484
/** Provides logic related to SSA. */
8585
private module SsaFlow {
86-
module Impl = SsaImpl::DataFlowIntegration;
86+
private module Impl = SsaImpl::DataFlowIntegration;
87+
88+
private ParameterNodeImpl toParameterNode(SsaImpl::ParameterExt p) {
89+
result = TNormalParameterNode(p.asParameter())
90+
or
91+
result = TSelfMethodParameterNode(p.asMethodSelf())
92+
or
93+
result = TSelfToplevelParameterNode(p.asToplevelSelf())
94+
}
8795

8896
Impl::Node asNode(Node n) {
8997
n = TSsaNode(result)
@@ -92,11 +100,11 @@ private module SsaFlow {
92100
or
93101
result.(Impl::ExprPostUpdateNode).getExpr() = n.(PostUpdateNode).getPreUpdateNode().asExpr()
94102
or
95-
n = result.(Impl::ParameterNode).getParameter().toParameterNode()
103+
n = toParameterNode(result.(Impl::ParameterNode).getParameter())
96104
}
97105

98-
predicate localFlowStep(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo) {
99-
Impl::localFlowStep(def, asNode(nodeFrom), asNode(nodeTo))
106+
predicate localFlowStep(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo, boolean isUseStep) {
107+
Impl::localFlowStep(def, asNode(nodeFrom), asNode(nodeTo), isUseStep)
100108
}
101109

102110
predicate localMustFlowStep(SsaImpl::DefinitionExt def, Node nodeFrom, Node nodeTo) {
@@ -436,7 +444,7 @@ private module Cached {
436444
newtype TNode =
437445
TExprNode(CfgNodes::ExprCfgNode n) or
438446
TReturningNode(CfgNodes::ReturningCfgNode n) { exists(n.getReturnedValueNode()) } or
439-
TSsaNode(SsaFlow::Impl::SsaNode node) or
447+
TSsaNode(SsaImpl::DataFlowIntegration::SsaNode node) or
440448
TCapturedVariableNode(VariableCapture::CapturedVariable v) or
441449
TNormalParameterNode(SsaImpl::NormalParameter p) or
442450
TSelfMethodParameterNode(MethodBase m) or
@@ -507,10 +515,13 @@ private module Cached {
507515
(
508516
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
509517
or
510-
exists(SsaImpl::DefinitionExt def |
511-
SsaFlow::localFlowStep(def, nodeFrom, nodeTo) and
518+
exists(SsaImpl::DefinitionExt def, boolean isUseStep |
519+
SsaFlow::localFlowStep(def, nodeFrom, nodeTo, isUseStep) and
512520
// captured variables are handled by the shared `VariableCapture` library
513-
not def instanceof VariableCapture::CapturedSsaDefinitionExt and
521+
not def instanceof VariableCapture::CapturedSsaDefinitionExt
522+
|
523+
isUseStep = false
524+
or
514525
not FlowSummaryImpl::Private::Steps::prohibitsUseUseFlow(nodeFrom, _)
515526
)
516527
or
@@ -526,7 +537,7 @@ private module Cached {
526537
predicate localFlowStepImpl(Node nodeFrom, Node nodeTo) {
527538
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
528539
or
529-
SsaFlow::localFlowStep(_, nodeFrom, nodeTo)
540+
SsaFlow::localFlowStep(_, nodeFrom, nodeTo, _)
530541
or
531542
// Simple flow through library code is included in the exposed local
532543
// step relation, even though flow is technically inter-procedural
@@ -540,7 +551,7 @@ private module Cached {
540551
predicate localFlowStepTypeTracker(Node nodeFrom, Node nodeTo) {
541552
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
542553
or
543-
SsaFlow::localFlowStep(_, nodeFrom, nodeTo)
554+
SsaFlow::localFlowStep(_, nodeFrom, nodeTo, _)
544555
or
545556
VariableCapture::flowInsensitiveStep(nodeFrom, nodeTo)
546557
or
@@ -745,7 +756,7 @@ predicate nodeIsHidden(Node n) {
745756

746757
/** An SSA node. */
747758
abstract class SsaNode extends NodeImpl, TSsaNode {
748-
SsaFlow::Impl::SsaNode node;
759+
SsaImpl::DataFlowIntegration::SsaNode node;
749760
SsaImpl::DefinitionExt def;
750761

751762
SsaNode() {
@@ -765,7 +776,7 @@ abstract class SsaNode extends NodeImpl, TSsaNode {
765776

766777
/** An (extended) SSA definition, viewed as a node in a data flow graph. */
767778
class SsaDefinitionExtNode extends SsaNode {
768-
override SsaFlow::Impl::SsaDefinitionExtNode node;
779+
override SsaImpl::DataFlowIntegration::SsaDefinitionExtNode node;
769780

770781
/** Gets the underlying variable. */
771782
Variable getVariable() { result = def.getSourceVariable() }
@@ -827,7 +838,7 @@ class SsaDefinitionNodeImpl extends SsaDefinitionExtNode {
827838
* both inputs into the phi read node after the outer condition are guarded.
828839
*/
829840
class SsaInputNode extends SsaNode {
830-
override SsaFlow::Impl::SsaInputNode node;
841+
override SsaImpl::DataFlowIntegration::SsaInputNode node;
831842

832843
override predicate isHidden() { any() }
833844

ruby/ql/lib/codeql/ruby/dataflow/internal/SsaImpl.qll

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ private import codeql.ruby.controlflow.internal.ControlFlowGraphImpl as ControlF
55
private import codeql.ruby.dataflow.SSA
66
private import codeql.ruby.ast.Variable
77
private import Cfg::CfgNodes::ExprNodes
8-
private import DataFlowPrivate
98

109
module SsaInput implements SsaImplCommon::InputSig<Location> {
1110
private import codeql.ruby.controlflow.ControlFlowGraph as Cfg
@@ -421,13 +420,24 @@ private module Cached {
421420
Impl::uncertainWriteDefinitionInput(def, result)
422421
}
423422

424-
private import TaintTrackingPrivate as TaintTrackingPrivate
425-
426423
cached
427-
predicate forceCachingInSameStage() {
428-
// needed in order to avoid recomputing SSA predicates in the `Integration` module
429-
DataFlowIntegration::localFlowStep(_, _, _) and
430-
TaintTrackingPrivate::forceCachingInSameStage()
424+
module DataFlowIntegration {
425+
import DataFlowIntegrationImpl
426+
427+
cached
428+
predicate localFlowStep(DefinitionExt def, Node nodeFrom, Node nodeTo, boolean isUseStep) {
429+
DataFlowIntegrationImpl::localFlowStep(def, nodeFrom, nodeTo, isUseStep)
430+
}
431+
432+
cached
433+
predicate localMustFlowStep(DefinitionExt def, Node nodeFrom, Node nodeTo) {
434+
DataFlowIntegrationImpl::localMustFlowStep(def, nodeFrom, nodeTo)
435+
}
436+
437+
cached
438+
Node getABarrierNode(Cfg::CfgNodes::AstCfgNode guard, Ssa::Definition def, boolean branch) {
439+
result = DataFlowIntegrationImpl::getABarrierNode(guard, def, branch)
440+
}
431441
}
432442

433443
bindingset[def1, def2]
@@ -517,14 +527,6 @@ class ParameterExt extends TParameterExt {
517527

518528
Toplevel asToplevelSelf() { this = TSelfToplevelParameter(result) }
519529

520-
ParameterNodeImpl toParameterNode() {
521-
result = TNormalParameterNode(this.asParameter())
522-
or
523-
result = TSelfMethodParameterNode(this.asMethodSelf())
524-
or
525-
result = TSelfToplevelParameterNode(this.asToplevelSelf())
526-
}
527-
528530
predicate isInitializedBy(WriteDefinition def) {
529531
def = getParameterDef(this.asParameter())
530532
or
@@ -584,4 +586,4 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
584586
}
585587
}
586588

587-
module DataFlowIntegration = Impl::DataFlowIntegration<DataFlowIntegrationInput>;
589+
private module DataFlowIntegrationImpl = Impl::DataFlowIntegration<DataFlowIntegrationInput>;

0 commit comments

Comments
 (0)