Skip to content

Commit 70a871c

Browse files
authored
Merge pull request #20253 from aschackmull/shared/basicblock-signature2
Shared: Add and use a signature for basic blocks
2 parents cbdc54a + 09b2c5a commit 70a871c

File tree

47 files changed

+825
-657
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+825
-657
lines changed

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1880,9 +1880,7 @@ module IteratorFlow {
18801880
}
18811881
}
18821882

1883-
private module SsaInput implements SsaImpl::InputSig<Location> {
1884-
import Ssa::InputSigCommon
1885-
1883+
private module SsaInput implements SsaImpl::InputSig<Location, IRCfg::BasicBlock> {
18861884
class SourceVariable = IteratorFlow::SourceVariable;
18871885

18881886
/** A call to function that dereferences an iterator. */
@@ -1960,7 +1958,7 @@ module IteratorFlow {
19601958
* Holds if `(bb, i)` contains a write to an iterator that may have been obtained
19611959
* by calling `begin` (or related functions) on the variable `v`.
19621960
*/
1963-
predicate variableWrite(BasicBlock bb, int i, SourceVariable v, boolean certain) {
1961+
predicate variableWrite(IRCfg::BasicBlock bb, int i, SourceVariable v, boolean certain) {
19641962
certain = false and
19651963
exists(GetsIteratorCall beginCall, Instruction writeToDeref, IRBlock bbQual, int iQual |
19661964
isIteratorStoreInstruction(beginCall, writeToDeref) and
@@ -1971,12 +1969,12 @@ module IteratorFlow {
19711969
}
19721970

19731971
/** Holds if `(bb, i)` reads the container variable `v`. */
1974-
predicate variableRead(BasicBlock bb, int i, SourceVariable v, boolean certain) {
1972+
predicate variableRead(IRCfg::BasicBlock bb, int i, SourceVariable v, boolean certain) {
19751973
Ssa::variableRead(bb, i, v, certain)
19761974
}
19771975
}
19781976

1979-
private module IteratorSsa = SsaImpl::Make<Location, SsaInput>;
1977+
private module IteratorSsa = SsaImpl::Make<Location, IRCfg, SsaInput>;
19801978

19811979
private module DataFlowIntegrationInput implements IteratorSsa::DataFlowIntegrationInputSig {
19821980
private import codeql.util.Void
@@ -1989,7 +1987,7 @@ module IteratorFlow {
19891987
)
19901988
}
19911989

1992-
predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { bb.getInstruction(i) = this }
1990+
predicate hasCfgNode(IRCfg::BasicBlock bb, int i) { bb.getInstruction(i) = this }
19931991
}
19941992

19951993
predicate ssaDefHasSource(IteratorSsa::WriteDefinition def) { none() }
@@ -1999,20 +1997,16 @@ module IteratorFlow {
19991997
class GuardValue = Void;
20001998

20011999
class Guard extends Void {
2002-
predicate hasValueBranchEdge(
2003-
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue val
2004-
) {
2000+
predicate hasValueBranchEdge(IRCfg::BasicBlock bb1, IRCfg::BasicBlock bb2, GuardValue val) {
20052001
none()
20062002
}
20072003

2008-
predicate valueControlsBranchEdge(
2009-
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue val
2010-
) {
2004+
predicate valueControlsBranchEdge(IRCfg::BasicBlock bb1, IRCfg::BasicBlock bb2, GuardValue val) {
20112005
none()
20122006
}
20132007
}
20142008

2015-
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, GuardValue val) {
2009+
predicate guardDirectlyControlsBlock(Guard guard, IRCfg::BasicBlock bb, GuardValue val) {
20162010
none()
20172011
}
20182012

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImpl.qll

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -891,15 +891,14 @@ private predicate baseSourceVariableIsGlobal(
891891
)
892892
}
893893

894-
private module SsaInput implements Ssa::InputSig<Location> {
895-
import InputSigCommon
894+
private module SsaInput implements Ssa::InputSig<Location, IRCfg::BasicBlock> {
896895
import SourceVariables
897896

898897
/**
899898
* Holds if the `i`'th write in block `bb` writes to the variable `v`.
900899
* `certain` is `true` if the write is guaranteed to overwrite the entire variable.
901900
*/
902-
predicate variableWrite(BasicBlock bb, int i, SourceVariable v, boolean certain) {
901+
predicate variableWrite(IRCfg::BasicBlock bb, int i, SourceVariable v, boolean certain) {
903902
DataFlowImplCommon::forceCachingInSameStage() and
904903
(
905904
exists(DefImpl def | def.hasIndexInBlock(v, bb, i) |
@@ -917,7 +916,7 @@ private module SsaInput implements Ssa::InputSig<Location> {
917916
* Holds if the `i`'th read in block `bb` reads to the variable `v`.
918917
* `certain` is `true` if the read is guaranteed. For C++, this is always the case.
919918
*/
920-
predicate variableRead(BasicBlock bb, int i, SourceVariable v, boolean certain) {
919+
predicate variableRead(IRCfg::BasicBlock bb, int i, SourceVariable v, boolean certain) {
921920
exists(UseImpl use | use.hasIndexInBlock(bb, i, v) |
922921
if use.isCertain() then certain = true else certain = false
923922
)
@@ -965,7 +964,7 @@ class GlobalDef extends Definition {
965964
GlobalLikeVariable getVariable() { result = impl.getVariable() }
966965
}
967966

968-
private module SsaImpl = Ssa::Make<Location, SsaInput>;
967+
private module SsaImpl = Ssa::Make<Location, IRCfg, SsaInput>;
969968

970969
private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationInputSig {
971970
private import codeql.util.Boolean
@@ -978,7 +977,7 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
978977
)
979978
}
980979

981-
predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { bb.getInstruction(i) = this }
980+
predicate hasCfgNode(IRCfg::BasicBlock bb, int i) { bb.getInstruction(i) = this }
982981
}
983982

984983
Expr getARead(SsaImpl::Definition def) {
@@ -1006,9 +1005,7 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
10061005
class Guard instanceof IRGuards::IRGuardCondition {
10071006
string toString() { result = super.toString() }
10081007

1009-
predicate hasValueBranchEdge(
1010-
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue branch
1011-
) {
1008+
predicate hasValueBranchEdge(IRCfg::BasicBlock bb1, IRCfg::BasicBlock bb2, GuardValue branch) {
10121009
exists(EdgeKind kind |
10131010
super.getBlock() = bb1 and
10141011
kind = getConditionalEdge(branch) and
@@ -1017,13 +1014,13 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
10171014
}
10181015

10191016
predicate valueControlsBranchEdge(
1020-
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, GuardValue branch
1017+
IRCfg::BasicBlock bb1, IRCfg::BasicBlock bb2, GuardValue branch
10211018
) {
10221019
this.hasValueBranchEdge(bb1, bb2, branch)
10231020
}
10241021
}
10251022

1026-
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, GuardValue branch) {
1023+
predicate guardDirectlyControlsBlock(Guard guard, IRCfg::BasicBlock bb, GuardValue branch) {
10271024
guard.(IRGuards::IRGuardCondition).controls(bb, branch)
10281025
}
10291026

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaImplCommon.qll

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -768,21 +768,3 @@ private module Cached {
768768
}
769769

770770
import Cached
771-
772-
/**
773-
* Inputs to the shared SSA library's parameterized module that is shared
774-
* between the SSA pruning stage, and the final SSA stage.
775-
*/
776-
module InputSigCommon {
777-
class BasicBlock extends IRBlock {
778-
ControlFlowNode getNode(int i) { result = this.getInstruction(i) }
779-
780-
int length() { result = this.getInstructionCount() }
781-
}
782-
783-
class ControlFlowNode = Instruction;
784-
785-
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result.immediatelyDominates(bb) }
786-
787-
BasicBlock getABasicBlockSuccessor(BasicBlock bb) { result = bb.getASuccessor() }
788-
}

cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/IRBlock.qll

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Instruction
77
private import internal.IRBlockImports as Imports
88
import Imports::EdgeKind
99
private import Cached
10+
private import codeql.controlflow.BasicBlock as BB
1011

1112
/**
1213
* Holds if `block` is a block in `func` and `sortOverride`, `sortKey1`, and `sortKey2` are the
@@ -263,6 +264,49 @@ private predicate isEntryBlock(TIRBlock block) {
263264
block = MkIRBlock(any(EnterFunctionInstruction enter))
264265
}
265266

267+
module IRCfg implements BB::CfgSig<Language::Location> {
268+
class ControlFlowNode = Instruction;
269+
270+
class SuccessorType = EdgeKind;
271+
272+
final private class FinalIRBlock = IRBlock;
273+
274+
class BasicBlock extends FinalIRBlock {
275+
ControlFlowNode getNode(int i) { result = this.getInstruction(i) }
276+
277+
ControlFlowNode getLastNode() { result = super.getLastInstruction() }
278+
279+
int length() { result = this.getInstructionCount() }
280+
281+
BasicBlock getASuccessor() { result = super.getASuccessor() }
282+
283+
BasicBlock getASuccessor(SuccessorType t) { result = super.getSuccessor(t) }
284+
285+
predicate strictlyDominates(BasicBlock bb) { super.strictlyDominates(bb) }
286+
287+
predicate dominates(BasicBlock bb) { super.dominates(bb) }
288+
289+
BasicBlock getImmediateDominator() { result.immediatelyDominates(this) }
290+
291+
predicate inDominanceFrontier(BasicBlock df) { super.dominanceFrontier() = df }
292+
293+
predicate strictlyPostDominates(BasicBlock bb) { super.strictlyPostDominates(bb) }
294+
295+
predicate postDominates(BasicBlock bb) { super.postDominates(bb) }
296+
}
297+
298+
class EntryBasicBlock extends BasicBlock {
299+
EntryBasicBlock() { isEntryBlock(this) }
300+
}
301+
302+
pragma[nomagic]
303+
predicate dominatingEdge(BasicBlock bb1, BasicBlock bb2) {
304+
bb1.getASuccessor() = bb2 and
305+
bb1 = bb2.getImmediateDominator() and
306+
forall(BasicBlock pred | pred = bb2.getAPredecessor() and pred != bb1 | bb2.dominates(pred))
307+
}
308+
}
309+
266310
cached
267311
private module Cached {
268312
cached

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/IRBlock.qll

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Instruction
77
private import internal.IRBlockImports as Imports
88
import Imports::EdgeKind
99
private import Cached
10+
private import codeql.controlflow.BasicBlock as BB
1011

1112
/**
1213
* Holds if `block` is a block in `func` and `sortOverride`, `sortKey1`, and `sortKey2` are the
@@ -263,6 +264,49 @@ private predicate isEntryBlock(TIRBlock block) {
263264
block = MkIRBlock(any(EnterFunctionInstruction enter))
264265
}
265266

267+
module IRCfg implements BB::CfgSig<Language::Location> {
268+
class ControlFlowNode = Instruction;
269+
270+
class SuccessorType = EdgeKind;
271+
272+
final private class FinalIRBlock = IRBlock;
273+
274+
class BasicBlock extends FinalIRBlock {
275+
ControlFlowNode getNode(int i) { result = this.getInstruction(i) }
276+
277+
ControlFlowNode getLastNode() { result = super.getLastInstruction() }
278+
279+
int length() { result = this.getInstructionCount() }
280+
281+
BasicBlock getASuccessor() { result = super.getASuccessor() }
282+
283+
BasicBlock getASuccessor(SuccessorType t) { result = super.getSuccessor(t) }
284+
285+
predicate strictlyDominates(BasicBlock bb) { super.strictlyDominates(bb) }
286+
287+
predicate dominates(BasicBlock bb) { super.dominates(bb) }
288+
289+
BasicBlock getImmediateDominator() { result.immediatelyDominates(this) }
290+
291+
predicate inDominanceFrontier(BasicBlock df) { super.dominanceFrontier() = df }
292+
293+
predicate strictlyPostDominates(BasicBlock bb) { super.strictlyPostDominates(bb) }
294+
295+
predicate postDominates(BasicBlock bb) { super.postDominates(bb) }
296+
}
297+
298+
class EntryBasicBlock extends BasicBlock {
299+
EntryBasicBlock() { isEntryBlock(this) }
300+
}
301+
302+
pragma[nomagic]
303+
predicate dominatingEdge(BasicBlock bb1, BasicBlock bb2) {
304+
bb1.getASuccessor() = bb2 and
305+
bb1 = bb2.getImmediateDominator() and
306+
forall(BasicBlock pred | pred = bb2.getAPredecessor() and pred != bb1 | bb2.dominates(pred))
307+
}
308+
}
309+
266310
cached
267311
private module Cached {
268312
cached

cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/IRBlock.qll

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Instruction
77
private import internal.IRBlockImports as Imports
88
import Imports::EdgeKind
99
private import Cached
10+
private import codeql.controlflow.BasicBlock as BB
1011

1112
/**
1213
* Holds if `block` is a block in `func` and `sortOverride`, `sortKey1`, and `sortKey2` are the
@@ -263,6 +264,49 @@ private predicate isEntryBlock(TIRBlock block) {
263264
block = MkIRBlock(any(EnterFunctionInstruction enter))
264265
}
265266

267+
module IRCfg implements BB::CfgSig<Language::Location> {
268+
class ControlFlowNode = Instruction;
269+
270+
class SuccessorType = EdgeKind;
271+
272+
final private class FinalIRBlock = IRBlock;
273+
274+
class BasicBlock extends FinalIRBlock {
275+
ControlFlowNode getNode(int i) { result = this.getInstruction(i) }
276+
277+
ControlFlowNode getLastNode() { result = super.getLastInstruction() }
278+
279+
int length() { result = this.getInstructionCount() }
280+
281+
BasicBlock getASuccessor() { result = super.getASuccessor() }
282+
283+
BasicBlock getASuccessor(SuccessorType t) { result = super.getSuccessor(t) }
284+
285+
predicate strictlyDominates(BasicBlock bb) { super.strictlyDominates(bb) }
286+
287+
predicate dominates(BasicBlock bb) { super.dominates(bb) }
288+
289+
BasicBlock getImmediateDominator() { result.immediatelyDominates(this) }
290+
291+
predicate inDominanceFrontier(BasicBlock df) { super.dominanceFrontier() = df }
292+
293+
predicate strictlyPostDominates(BasicBlock bb) { super.strictlyPostDominates(bb) }
294+
295+
predicate postDominates(BasicBlock bb) { super.postDominates(bb) }
296+
}
297+
298+
class EntryBasicBlock extends BasicBlock {
299+
EntryBasicBlock() { isEntryBlock(this) }
300+
}
301+
302+
pragma[nomagic]
303+
predicate dominatingEdge(BasicBlock bb1, BasicBlock bb2) {
304+
bb1.getASuccessor() = bb2 and
305+
bb1 = bb2.getImmediateDominator() and
306+
forall(BasicBlock pred | pred = bb2.getAPredecessor() and pred != bb1 | bb2.dominates(pred))
307+
}
308+
}
309+
266310
cached
267311
private module Cached {
268312
cached

csharp/ql/consistency-queries/CfgConsistency.ql

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ predicate bbSuccInconsistency(ControlFlowElement pred, ControlFlowElement succ)
2929
succBB.getFirstNode() = succ.getAControlFlowNode()
3030
) and
3131
not exists(PreBasicBlock predBB, PreBasicBlock succBB |
32-
predBB.getLastElement() = pred and
32+
predBB.getLastNode() = pred and
3333
succBB = predBB.getASuccessor() and
3434
succBB.getFirstElement() = succ
3535
)
@@ -41,12 +41,12 @@ predicate bbIntraSuccInconsistency(ControlFlowElement pred, ControlFlowElement s
4141
succ.getAControlFlowNode() = bb.getNode(i + 1)
4242
) and
4343
not exists(PreBasicBlock bb |
44-
bb.getLastElement() = pred and
44+
bb.getLastNode() = pred and
4545
bb.getASuccessor().getFirstElement() = succ
4646
) and
4747
not exists(PreBasicBlock bb, int i |
48-
bb.getElement(i) = pred and
49-
bb.getElement(i + 1) = succ
48+
bb.getNode(i) = pred and
49+
bb.getNode(i + 1) = succ
5050
)
5151
}
5252

0 commit comments

Comments
 (0)