Skip to content

Commit bc752e1

Browse files
Add post-dominators.
1 parent 10dc183 commit bc752e1

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed

cpp/ql/src/semmle/code/cpp/controlflow/Dominance.qll

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,39 @@ predicate functionEntry(ControlFlowNode entry) {
2828
and not hasMultiScopeNode(function))
2929
}
3030

31+
/** Holds if `exit` is the exit node of a function. */
32+
predicate functionExit(ControlFlowNode exit) {
33+
exists (Function function |
34+
function = exit
35+
and not hasMultiScopeNode(function))
36+
}
37+
3138
/**
3239
* Holds if `dest` is an immediate successor of `src` in the control-flow graph.
3340
*/
3441
private predicate nodeSucc(ControlFlowNode src, ControlFlowNode dest) {
3542
src.getASuccessor() = dest
3643
}
3744

45+
/**
46+
* Holds if `pred` is an immediate predecessor of `src` in the control-flow graph.
47+
*/
48+
private predicate nodePred(ControlFlowNode src, ControlFlowNode pred) {
49+
src.getAPredecessor() = pred
50+
}
51+
3852
/**
3953
* Holds if `dominator` is an immediate dominator of `node` in the control-flow
4054
* graph.
4155
*/
4256
predicate iDominates(ControlFlowNode dominator, ControlFlowNode node) = idominance(functionEntry/1,nodeSucc/2)(_, dominator, node)
4357

58+
/**
59+
* Holds if `postdominator` is an immediate post-dominator of `node` in the control-flow
60+
* graph.
61+
*/
62+
predicate iPostDominates(ControlFlowNode postdominator, ControlFlowNode node) = idominance(functionExit/1,nodePred/2)(_, postdominator, node)
63+
4464
/**
4565
* Holds if `dominator` is a strict dominator of `node` in the control-flow
4666
* graph. Being strict means that `dominator != node`.
@@ -49,6 +69,14 @@ predicate strictlyDominates(ControlFlowNode dominator, ControlFlowNode node) {
4969
iDominates+(dominator, node)
5070
}
5171

72+
/**
73+
* Holds if `postdominator` is a strict post-dominator of `node` in the control-flow
74+
* graph. Being strict means that `postdominator != node`.
75+
*/
76+
predicate strictlyPostDominates(ControlFlowNode postdominator, ControlFlowNode node) {
77+
iPostDominates+(postdominator, node)
78+
}
79+
5280
/**
5381
* Holds if `dominator` is a dominator of `node` in the control-flow graph. This
5482
* is reflexive.
@@ -57,6 +85,14 @@ predicate dominates(ControlFlowNode dominator, ControlFlowNode node) {
5785
strictlyDominates(dominator, node) or dominator = node
5886
}
5987

88+
/**
89+
* Holds if `postdominator` is a post-dominator of `node` in the control-flow graph. This
90+
* is reflexive.
91+
*/
92+
predicate postdominates(ControlFlowNode postdominator, ControlFlowNode node) {
93+
strictlyPostDominates(postdominator, node) or postdominator = node
94+
}
95+
6096
/*
6197
* Dominance predicates for basic blocks.
6298
*/
@@ -67,6 +103,25 @@ predicate dominates(ControlFlowNode dominator, ControlFlowNode node) {
67103
*/
68104
predicate bbIDominates(BasicBlock dom, BasicBlock node) = idominance(functionEntry/1, bb_successor/2)(_, dom, node)
69105

106+
/**
107+
* Holds if `pred` is a predecessor of `succ` in the control-flow graph of
108+
* basic blocks.
109+
*/
110+
private predicate bb_predecessor(BasicBlock succ, BasicBlock pred) {
111+
bb_successor(pred, succ)
112+
}
113+
114+
/** Holds if `exit` an `ExitBasicBlock`. */
115+
private predicate bb_exit(ExitBasicBlock exit) {
116+
any()
117+
}
118+
119+
/**
120+
* Holds if `postdominator` is an immediate post-dominator of `node` in the control-flow
121+
* graph of basic blocks.
122+
*/
123+
predicate bbIPostDominates(BasicBlock dom, BasicBlock node) = idominance(bb_exit/1, bb_predecessor/2)(_, dom, node)
124+
70125
/**
71126
* Holds if `dominator` is a strict dominator of `node` in the control-flow
72127
* graph of basic blocks. Being strict means that `dominator != node`.
@@ -75,6 +130,13 @@ predicate bbStrictlyDominates(BasicBlock dominator, BasicBlock node) {
75130
bbIDominates+(dominator, node)
76131
}
77132

133+
/**
134+
* Holds if `postdominator` is a strict post-dominator of `node` in the control-flow
135+
* graph of basic blocks. Being strict means that `postdominator != node`.
136+
*/
137+
predicate bbStrictlyPostDominates(BasicBlock postdominator, BasicBlock node) {
138+
bbIPostDominates+(postdominator, node)
139+
}
78140

79141
/**
80142
* Holds if `dominator` is a dominator of `node` in the control-flow graph of
@@ -83,3 +145,11 @@ predicate bbStrictlyDominates(BasicBlock dominator, BasicBlock node) {
83145
predicate bbDominates(BasicBlock dominator, BasicBlock node) {
84146
bbStrictlyDominates(dominator, node) or dominator = node
85147
}
148+
149+
/**
150+
* Holds if `postdominator` is a post-dominator of `node` in the control-flow graph of
151+
* basic blocks. This is reflexive.
152+
*/
153+
predicate bbPostDominates(BasicBlock postdominator, BasicBlock node) {
154+
bbStrictlyPostDominates(postdominator, node) or postdominator = node
155+
}

0 commit comments

Comments
 (0)