Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b40acce

Browse files
committed
C++: sanity checks for back edges
1 parent 38f7ec7 commit b40acce

6 files changed

Lines changed: 153 additions & 0 deletions

File tree

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,54 @@ module InstructionSanity {
131131
blockCount = count(instr.getBlock()) and
132132
blockCount != 1
133133
}
134+
135+
private predicate forwardEdge(IRBlock b1, IRBlock b2) {
136+
b1.getASuccessor() = b2 and
137+
not b1.getBackEdgeSuccessor(_) = b2
138+
}
139+
140+
/**
141+
* Holds if `f` contains a loop in which no edge is a back edge.
142+
*
143+
* This check ensures we don't have too _few_ back edges.
144+
*/
145+
query predicate containsLoopOfForwardEdges(FunctionIR f) {
146+
exists(IRBlock block |
147+
forwardEdge+(block, block) and
148+
block.getFunctionIR() = f
149+
)
150+
}
151+
152+
/**
153+
* Holds if `block` is reachable from its function entry point but would not
154+
* be reachable by traversing only forward edges. This check is skipped for
155+
* functions containing `goto` statements as the property does not generally
156+
* hold there.
157+
*
158+
* This check ensures we don't have too _many_ back edges.
159+
*/
160+
query predicate lostReachability(IRBlock block) {
161+
exists(FunctionIR f, IRBlock entry |
162+
entry = f.getEntryBlock() and
163+
entry.getASuccessor+() = block and
164+
not forwardEdge+(entry, block) and
165+
not exists(GotoStmt s | s.getEnclosingFunction() = f.getFunction())
166+
)
167+
}
168+
169+
/**
170+
* Holds if the number of back edges differs between the `Instruction` graph
171+
* and the `IRBlock` graph.
172+
*/
173+
query predicate backEdgeCountMismatch(Function f, int fromInstr, int fromBlock) {
174+
fromInstr = count(Instruction i1, Instruction i2 |
175+
i1.getFunction() = f and i1.getBackEdgeSuccessor(_) = i2
176+
) and
177+
fromBlock = count(IRBlock b1, IRBlock b2 |
178+
b1.getFunction() = f and b1.getBackEdgeSuccessor(_) = b2
179+
) and
180+
fromInstr != fromBlock
181+
}
134182
}
135183

136184
/**

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,54 @@ module InstructionSanity {
131131
blockCount = count(instr.getBlock()) and
132132
blockCount != 1
133133
}
134+
135+
private predicate forwardEdge(IRBlock b1, IRBlock b2) {
136+
b1.getASuccessor() = b2 and
137+
not b1.getBackEdgeSuccessor(_) = b2
138+
}
139+
140+
/**
141+
* Holds if `f` contains a loop in which no edge is a back edge.
142+
*
143+
* This check ensures we don't have too _few_ back edges.
144+
*/
145+
query predicate containsLoopOfForwardEdges(FunctionIR f) {
146+
exists(IRBlock block |
147+
forwardEdge+(block, block) and
148+
block.getFunctionIR() = f
149+
)
150+
}
151+
152+
/**
153+
* Holds if `block` is reachable from its function entry point but would not
154+
* be reachable by traversing only forward edges. This check is skipped for
155+
* functions containing `goto` statements as the property does not generally
156+
* hold there.
157+
*
158+
* This check ensures we don't have too _many_ back edges.
159+
*/
160+
query predicate lostReachability(IRBlock block) {
161+
exists(FunctionIR f, IRBlock entry |
162+
entry = f.getEntryBlock() and
163+
entry.getASuccessor+() = block and
164+
not forwardEdge+(entry, block) and
165+
not exists(GotoStmt s | s.getEnclosingFunction() = f.getFunction())
166+
)
167+
}
168+
169+
/**
170+
* Holds if the number of back edges differs between the `Instruction` graph
171+
* and the `IRBlock` graph.
172+
*/
173+
query predicate backEdgeCountMismatch(Function f, int fromInstr, int fromBlock) {
174+
fromInstr = count(Instruction i1, Instruction i2 |
175+
i1.getFunction() = f and i1.getBackEdgeSuccessor(_) = i2
176+
) and
177+
fromBlock = count(IRBlock b1, IRBlock b2 |
178+
b1.getFunction() = f and b1.getBackEdgeSuccessor(_) = b2
179+
) and
180+
fromInstr != fromBlock
181+
}
134182
}
135183

136184
/**

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,54 @@ module InstructionSanity {
131131
blockCount = count(instr.getBlock()) and
132132
blockCount != 1
133133
}
134+
135+
private predicate forwardEdge(IRBlock b1, IRBlock b2) {
136+
b1.getASuccessor() = b2 and
137+
not b1.getBackEdgeSuccessor(_) = b2
138+
}
139+
140+
/**
141+
* Holds if `f` contains a loop in which no edge is a back edge.
142+
*
143+
* This check ensures we don't have too _few_ back edges.
144+
*/
145+
query predicate containsLoopOfForwardEdges(FunctionIR f) {
146+
exists(IRBlock block |
147+
forwardEdge+(block, block) and
148+
block.getFunctionIR() = f
149+
)
150+
}
151+
152+
/**
153+
* Holds if `block` is reachable from its function entry point but would not
154+
* be reachable by traversing only forward edges. This check is skipped for
155+
* functions containing `goto` statements as the property does not generally
156+
* hold there.
157+
*
158+
* This check ensures we don't have too _many_ back edges.
159+
*/
160+
query predicate lostReachability(IRBlock block) {
161+
exists(FunctionIR f, IRBlock entry |
162+
entry = f.getEntryBlock() and
163+
entry.getASuccessor+() = block and
164+
not forwardEdge+(entry, block) and
165+
not exists(GotoStmt s | s.getEnclosingFunction() = f.getFunction())
166+
)
167+
}
168+
169+
/**
170+
* Holds if the number of back edges differs between the `Instruction` graph
171+
* and the `IRBlock` graph.
172+
*/
173+
query predicate backEdgeCountMismatch(Function f, int fromInstr, int fromBlock) {
174+
fromInstr = count(Instruction i1, Instruction i2 |
175+
i1.getFunction() = f and i1.getBackEdgeSuccessor(_) = i2
176+
) and
177+
fromBlock = count(IRBlock b1, IRBlock b2 |
178+
b1.getFunction() = f and b1.getBackEdgeSuccessor(_) = b2
179+
) and
180+
fromInstr != fromBlock
181+
}
134182
}
135183

136184
/**

cpp/ql/test/library-tests/ir/ir/aliased_ssa_sanity.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@ instructionWithoutSuccessor
66
unnecessaryPhiInstruction
77
operandAcrossFunctions
88
instructionWithoutUniqueBlock
9+
containsLoopOfForwardEdges
10+
lostReachability
11+
backEdgeCountMismatch

cpp/ql/test/library-tests/ir/ir/raw_sanity.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@ instructionWithoutSuccessor
66
unnecessaryPhiInstruction
77
operandAcrossFunctions
88
instructionWithoutUniqueBlock
9+
containsLoopOfForwardEdges
10+
lostReachability
11+
backEdgeCountMismatch

cpp/ql/test/library-tests/ir/ir/unaliased_ssa_sanity.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@ instructionWithoutSuccessor
66
unnecessaryPhiInstruction
77
operandAcrossFunctions
88
instructionWithoutUniqueBlock
9+
containsLoopOfForwardEdges
10+
lostReachability
11+
backEdgeCountMismatch

0 commit comments

Comments
 (0)