Skip to content

Commit 55a3880

Browse files
authored
Merge pull request #4673 from MathiasVP/ir-post-dominance
C++: IR post dominance
2 parents f2259de + 27aab40 commit 55a3880

File tree

5 files changed

+245
-0
lines changed

5 files changed

+245
-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)

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/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)

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_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)

csharp/ql/src/experimental/ir/implementation/raw/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)

csharp/ql/src/experimental/ir/implementation/unaliased_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)