Skip to content

Commit 088d586

Browse files
committed
C++: Implement IR post-dominance predicates.
1 parent 19fac60 commit 088d586

File tree

1 file changed

+49
-0
lines changed
  • cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa

1 file changed

+49
-0
lines changed

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

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,46 @@ class IRBlock extends IRBlockBase {
163163
not strictlyDominates(result)
164164
}
165165

166+
/**
167+
* Holds if this block immediately post-dominates `block`.
168+
*
169+
* Block `A` immediate post-dominates block `B` if block `A` strictly post-dominates block `B` and
170+
* block `B` is a direct successor of block `A`.
171+
*/
172+
final predicate immediatelyPostDominates(IRBlock block) {
173+
blockImmediatelyPostDominates(this, block)
174+
}
175+
176+
/**
177+
* Holds if this block strictly post-dominates `block`.
178+
*
179+
* Block `A` strictly post-dominates block `B` if block `A` post-dominates block `B` and blocks `A`
180+
* and `B` are not the same block.
181+
*/
182+
final predicate strictlyPostDominates(IRBlock block) {
183+
blockImmediatelyPostDominates+(this, block)
184+
}
185+
186+
/**
187+
* Holds if this block is a post-dominator of `block`.
188+
*
189+
* Block `A` post-dominates block `B` if any control flow path from `B` to the exit block of the
190+
* function must pass through block `A`. A block always post-dominates itself.
191+
*/
192+
final predicate postDominates(IRBlock block) { strictlyPostDominates(block) or this = block }
193+
194+
/**
195+
* Gets a block on the post-dominance frontier of this block.
196+
*
197+
* The post-dominance frontier of block `A` is the set of blocks `B` such that block `A` does not
198+
* post-dominate block `B`, but block `A` does post-dominate an immediate successor of block `B`.
199+
*/
200+
pragma[noinline]
201+
final IRBlock postPominanceFrontier() {
202+
postDominates(result.getASuccessor()) and
203+
not strictlyPostDominates(result)
204+
}
205+
166206
/**
167207
* Holds if this block is reachable from the entry block of its function.
168208
*/
@@ -280,3 +320,12 @@ private module Cached {
280320
}
281321

282322
private Instruction getFirstInstruction(TIRBlock block) { block = MkIRBlock(result) }
323+
324+
private predicate blockFunctionExit(IRBlock exit) {
325+
exit.getLastInstruction() instanceof ExitFunctionInstruction
326+
}
327+
328+
private predicate blockPredecessor(IRBlock src, IRBlock pred) { src.getAPredecessor() = pred }
329+
330+
private predicate blockImmediatelyPostDominates(IRBlock postDominator, IRBlock block) =
331+
idominance(blockFunctionExit/1, blockPredecessor/2)(_, postDominator, block)

0 commit comments

Comments
 (0)