Skip to content

Commit da579c2

Browse files
authored
Merge pull request github#18934 from aschackmull/ssa/refactor5
SSA: Replace the Guards interface in the SSA data flow integration.
2 parents 61c043f + 5e722ee commit da579c2

File tree

7 files changed

+77
-100
lines changed

7 files changed

+77
-100
lines changed

csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImpl.qll

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,8 +1047,17 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
10471047
}
10481048

10491049
class Guard extends Guards::Guard {
1050-
predicate hasCfgNode(ControlFlow::BasicBlock bb, int i) {
1051-
this.getAControlFlowNode() = bb.getNode(i)
1050+
/**
1051+
* Holds if the control flow branching from `bb1` is dependent on this guard,
1052+
* and that the edge from `bb1` to `bb2` corresponds to the evaluation of this
1053+
* guard to `branch`.
1054+
*/
1055+
predicate controlsBranchEdge(BasicBlock bb1, BasicBlock bb2, boolean branch) {
1056+
exists(ControlFlow::SuccessorTypes::ConditionalSuccessor s |
1057+
this.getAControlFlowNode() = bb1.getLastNode() and
1058+
bb2 = bb1.getASuccessorByType(s) and
1059+
s.getValue() = branch
1060+
)
10521061
}
10531062
}
10541063

@@ -1060,16 +1069,6 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
10601069
conditionBlock.edgeDominates(bb, s)
10611070
)
10621071
}
1063-
1064-
/** Gets an immediate conditional successor of basic block `bb`, if any. */
1065-
ControlFlow::BasicBlock getAConditionalBasicBlockSuccessor(
1066-
ControlFlow::BasicBlock bb, boolean branch
1067-
) {
1068-
exists(ControlFlow::SuccessorTypes::ConditionalSuccessor s |
1069-
result = bb.getASuccessorByType(s) and
1070-
s.getValue() = branch
1071-
)
1072-
}
10731072
}
10741073

10751074
private module DataFlowIntegrationImpl = Impl::DataFlowIntegration<DataFlowIntegrationInput>;

java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -667,22 +667,20 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
667667
}
668668

669669
class Guard extends Guards::Guard {
670-
predicate hasCfgNode(BasicBlock bb, int i) {
671-
this = bb.getNode(i).asExpr()
672-
or
673-
this = bb.getNode(i).asStmt()
670+
/**
671+
* Holds if the control flow branching from `bb1` is dependent on this guard,
672+
* and that the edge from `bb1` to `bb2` corresponds to the evaluation of this
673+
* guard to `branch`.
674+
*/
675+
predicate controlsBranchEdge(BasicBlock bb1, BasicBlock bb2, boolean branch) {
676+
super.hasBranchEdge(bb1, bb2, branch)
674677
}
675678
}
676679

677680
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
678681
predicate guardControlsBlock(Guard guard, BasicBlock bb, boolean branch) {
679682
guard.controls(bb, branch)
680683
}
681-
682-
/** Gets an immediate conditional successor of basic block `bb`, if any. */
683-
BasicBlock getAConditionalBasicBlockSuccessor(BasicBlock bb, boolean branch) {
684-
result = bb.(Guards::ConditionBlock).getTestSuccessor(branch)
685-
}
686684
}
687685

688686
private module DataFlowIntegrationImpl = Impl::DataFlowIntegration<DataFlowIntegrationInput>;

javascript/ql/lib/semmle/javascript/dataflow/internal/sharedlib/Ssa.qll

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,19 @@ module SsaDataflowInput implements DataFlowIntegrationInputSig {
8181
class Guard extends js::ControlFlowNode {
8282
Guard() { this = any(js::ConditionGuardNode g).getTest() }
8383

84-
predicate hasCfgNode(js::BasicBlock bb, int i) { this = bb.getNode(i) }
84+
/**
85+
* Holds if the control flow branching from `bb1` is dependent on this guard,
86+
* and that the edge from `bb1` to `bb2` corresponds to the evaluation of this
87+
* guard to `branch`.
88+
*/
89+
predicate controlsBranchEdge(js::BasicBlock bb1, js::BasicBlock bb2, boolean branch) {
90+
exists(js::ConditionGuardNode g |
91+
g.getTest() = this and
92+
bb1 = this.getBasicBlock() and
93+
bb2 = g.getBasicBlock() and
94+
branch = g.getOutcome()
95+
)
96+
}
8597
}
8698

8799
pragma[inline]
@@ -92,14 +104,6 @@ module SsaDataflowInput implements DataFlowIntegrationInputSig {
92104
branch = g.getOutcome()
93105
)
94106
}
95-
96-
js::BasicBlock getAConditionalBasicBlockSuccessor(js::BasicBlock bb, boolean branch) {
97-
exists(js::ConditionGuardNode g |
98-
bb = g.getTest().getBasicBlock() and
99-
result = g.getBasicBlock() and
100-
branch = g.getOutcome()
101-
)
102-
}
103107
}
104108

105109
import DataFlowIntegration<SsaDataflowInput>

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,10 @@ CfgNodes::ExprCfgNode getAPostUpdateNodeForArg(Argument arg) {
7474

7575
/** Gets the SSA definition node corresponding to parameter `p`. */
7676
pragma[nomagic]
77-
SsaImpl::DefinitionExt getParameterDef(NamedParameter p) {
77+
Ssa::Definition getParameterDef(NamedParameter p) {
7878
exists(BasicBlock bb, int i |
7979
bb.getNode(i).getAstNode() = p.getDefiningAccess() and
80-
result.definesAt(_, bb, i, _)
80+
result.definesAt(_, bb, i)
8181
)
8282
}
8383

@@ -388,15 +388,15 @@ module VariableCapture {
388388
Flow::clearsContent(asClosureNode(node), c.getVariable())
389389
}
390390

391-
class CapturedSsaDefinitionExt extends SsaImpl::DefinitionExt {
392-
CapturedSsaDefinitionExt() { this.getSourceVariable() instanceof CapturedVariable }
391+
class CapturedSsaDefinition extends SsaImpl::Definition {
392+
CapturedSsaDefinition() { this.getSourceVariable() instanceof CapturedVariable }
393393
}
394394

395395
// From an assignment or implicit initialization of a captured variable to its flow-insensitive node
396396
private predicate flowInsensitiveWriteStep(
397397
SsaDefinitionNodeImpl node1, CapturedVariableNode node2, CapturedVariable v
398398
) {
399-
exists(CapturedSsaDefinitionExt def |
399+
exists(CapturedSsaDefinition def |
400400
def = node1.getDefinition() and
401401
def.getSourceVariable() = v and
402402
(
@@ -412,7 +412,7 @@ module VariableCapture {
412412
private predicate flowInsensitiveReadStep(
413413
CapturedVariableNode node1, SsaDefinitionNodeImpl node2, CapturedVariable v
414414
) {
415-
exists(CapturedSsaDefinitionExt def |
415+
exists(CapturedSsaDefinition def |
416416
node1.getVariable() = v and
417417
def = node2.getDefinition() and
418418
def.getSourceVariable() = v and
@@ -772,7 +772,7 @@ class SsaNode extends NodeImpl, TSsaNode {
772772
class SsaDefinitionNodeImpl extends SsaNode {
773773
override SsaImpl::DataFlowIntegration::SsaDefinitionNode node;
774774

775-
SsaImpl::Definition getDefinition() { result = node.getDefinition() }
775+
Ssa::Definition getDefinition() { result = node.getDefinition() }
776776

777777
override predicate isHidden() {
778778
exists(SsaImpl::Definition def | def = this.getDefinition() |
@@ -2478,7 +2478,7 @@ module TypeInference {
24782478
n = def or
24792479
n.asExpr() =
24802480
any(CfgNodes::ExprCfgNode read |
2481-
read = def.getDefinition().(SsaImpl::DefinitionExt).getARead() and
2481+
read = def.getDefinition().getARead() and
24822482
not isTypeCheckedRead(read, _) // could in principle be checked against a new type
24832483
)
24842484
)

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

Lines changed: 19 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -218,18 +218,18 @@ private predicate hasVariableReadWithCapturedWrite(
218218

219219
pragma[noinline]
220220
deprecated private predicate adjacentDefReadExt(
221-
DefinitionExt def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2,
221+
Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2,
222222
SsaInput::SourceVariable v
223223
) {
224224
Impl::adjacentDefReadExt(def, _, bb1, i1, bb2, i2) and
225225
v = def.getSourceVariable()
226226
}
227227

228228
deprecated private predicate adjacentDefReachesReadExt(
229-
DefinitionExt def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
229+
Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
230230
) {
231231
exists(SsaInput::SourceVariable v | adjacentDefReadExt(def, bb1, i1, bb2, i2, v) |
232-
def.definesAt(v, bb1, i1, _)
232+
def.definesAt(v, bb1, i1)
233233
or
234234
SsaInput::variableRead(bb1, i1, v, true)
235235
)
@@ -242,7 +242,7 @@ deprecated private predicate adjacentDefReachesReadExt(
242242
}
243243

244244
deprecated private predicate adjacentDefReachesUncertainReadExt(
245-
DefinitionExt def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
245+
Definition def, SsaInput::BasicBlock bb1, int i1, SsaInput::BasicBlock bb2, int i2
246246
) {
247247
adjacentDefReachesReadExt(def, bb1, i1, bb2, i2) and
248248
SsaInput::variableRead(bb2, i2, _, false)
@@ -251,7 +251,7 @@ deprecated private predicate adjacentDefReachesUncertainReadExt(
251251
/** Same as `lastRefRedef`, but skips uncertain reads. */
252252
pragma[nomagic]
253253
deprecated private predicate lastRefSkipUncertainReadsExt(
254-
DefinitionExt def, SsaInput::BasicBlock bb, int i
254+
Definition def, SsaInput::BasicBlock bb, int i
255255
) {
256256
Impl::lastRef(def, bb, i) and
257257
not SsaInput::variableRead(bb, i, def.getSourceVariable(), false)
@@ -413,33 +413,6 @@ private module Cached {
413413

414414
import Cached
415415

416-
/**
417-
* An extended static single assignment (SSA) definition.
418-
*
419-
* This is either a normal SSA definition (`Definition`) or a
420-
* phi-read node (`PhiReadNode`).
421-
*
422-
* Only intended for internal use.
423-
*/
424-
class DefinitionExt extends Impl::DefinitionExt {
425-
VariableReadAccessCfgNode getARead() { result = getARead(this) }
426-
427-
override string toString() { result = this.(Ssa::Definition).toString() }
428-
429-
override Location getLocation() { result = this.(Ssa::Definition).getLocation() }
430-
}
431-
432-
/**
433-
* A phi-read node.
434-
*
435-
* Only intended for internal use.
436-
*/
437-
class PhiReadNode extends DefinitionExt, Impl::PhiReadNode {
438-
override string toString() { result = "SSA phi read(" + this.getSourceVariable() + ")" }
439-
440-
override Location getLocation() { result = Impl::PhiReadNode.super.getLocation() }
441-
}
442-
443416
class NormalParameter extends Parameter {
444417
NormalParameter() {
445418
this instanceof SimpleParameter or
@@ -453,10 +426,10 @@ class NormalParameter extends Parameter {
453426

454427
/** Gets the SSA definition node corresponding to parameter `p`. */
455428
pragma[nomagic]
456-
DefinitionExt getParameterDef(NamedParameter p) {
429+
Definition getParameterDef(NamedParameter p) {
457430
exists(Cfg::BasicBlock bb, int i |
458431
bb.getNode(i).getAstNode() = p.getDefiningAccess() and
459-
result.definesAt(_, bb, i, _)
432+
result.definesAt(_, bb, i)
460433
)
461434
}
462435

@@ -515,21 +488,24 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
515488
predicate ssaDefInitializesParam(WriteDefinition def, Parameter p) { p.isInitializedBy(def) }
516489

517490
class Guard extends Cfg::CfgNodes::AstCfgNode {
518-
predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { this = bb.getNode(i) }
491+
/**
492+
* Holds if the control flow branching from `bb1` is dependent on this guard,
493+
* and that the edge from `bb1` to `bb2` corresponds to the evaluation of this
494+
* guard to `branch`.
495+
*/
496+
predicate controlsBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) {
497+
exists(Cfg::SuccessorTypes::ConditionalSuccessor s |
498+
this.getBasicBlock() = bb1 and
499+
bb2 = bb1.getASuccessor(s) and
500+
s.getValue() = branch
501+
)
502+
}
519503
}
520504

521505
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
522506
predicate guardControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
523507
Guards::guardControlsBlock(guard, bb, branch)
524508
}
525-
526-
/** Gets an immediate conditional successor of basic block `bb`, if any. */
527-
SsaInput::BasicBlock getAConditionalBasicBlockSuccessor(SsaInput::BasicBlock bb, boolean branch) {
528-
exists(Cfg::SuccessorTypes::ConditionalSuccessor s |
529-
result = bb.getASuccessor(s) and
530-
s.getValue() = branch
531-
)
532-
}
533509
}
534510

535511
private module DataFlowIntegrationImpl = Impl::DataFlowIntegration<DataFlowIntegrationInput>;

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

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,18 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
361361
}
362362

363363
class Guard extends CfgNodes::AstCfgNode {
364-
predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { this = bb.getNode(i) }
364+
/**
365+
* Holds if the control flow branching from `bb1` is dependent on this guard,
366+
* and that the edge from `bb1` to `bb2` corresponds to the evaluation of this
367+
* guard to `branch`.
368+
*/
369+
predicate controlsBranchEdge(SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch) {
370+
exists(Cfg::ConditionalSuccessor s |
371+
this = bb1.getANode() and
372+
bb2 = bb1.getASuccessor(s) and
373+
s.getValue() = branch
374+
)
375+
}
365376
}
366377

367378
/** Holds if the guard `guard` controls block `bb` upon evaluating to `branch`. */
@@ -372,14 +383,6 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
372383
conditionBlock.edgeDominates(bb, s)
373384
)
374385
}
375-
376-
/** Gets an immediate conditional successor of basic block `bb`, if any. */
377-
SsaInput::BasicBlock getAConditionalBasicBlockSuccessor(SsaInput::BasicBlock bb, boolean branch) {
378-
exists(Cfg::ConditionalSuccessor s |
379-
result = bb.getASuccessor(s) and
380-
s.getValue() = branch
381-
)
382-
}
383386
}
384387

385388
private module DataFlowIntegrationImpl = Impl::DataFlowIntegration<DataFlowIntegrationInput>;

shared/ssa/codeql/ssa/Ssa.qll

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,15 +1434,16 @@ module Make<LocationSig Location, InputSig<Location> Input> {
14341434
/** Gets a textual representation of this guard. */
14351435
string toString();
14361436

1437-
/** Holds if the `i`th node of basic block `bb` evaluates this guard. */
1438-
predicate hasCfgNode(BasicBlock bb, int i);
1437+
/**
1438+
* Holds if the control flow branching from `bb1` is dependent on this guard,
1439+
* and that the edge from `bb1` to `bb2` corresponds to the evaluation of this
1440+
* guard to `branch`.
1441+
*/
1442+
predicate controlsBranchEdge(BasicBlock bb1, BasicBlock bb2, boolean branch);
14391443
}
14401444

14411445
/** Holds if `guard` controls block `bb` upon evaluating to `branch`. */
14421446
predicate guardControlsBlock(Guard guard, BasicBlock bb, boolean branch);
1443-
1444-
/** Gets an immediate conditional successor of basic block `bb`, if any. */
1445-
BasicBlock getAConditionalBasicBlockSuccessor(BasicBlock bb, boolean branch);
14461447
}
14471448

14481449
/**
@@ -1891,11 +1892,7 @@ module Make<LocationSig Location, InputSig<Location> Input> {
18911892
|
18921893
DfInput::guardControlsBlock(g, bb, branch)
18931894
or
1894-
exists(int last |
1895-
last = bb.length() - 1 and
1896-
g.hasCfgNode(bb, last) and
1897-
DfInput::getAConditionalBasicBlockSuccessor(bb, branch) = phi.getBasicBlock()
1898-
)
1895+
g.controlsBranchEdge(bb, phi.getBasicBlock(), branch)
18991896
)
19001897
)
19011898
}

0 commit comments

Comments
 (0)