Skip to content

Commit ba8bf94

Browse files
committed
C++: Account for chi nodes in back-edge detection
1 parent 560dbdf commit ba8bf94

File tree

4 files changed

+26
-10
lines changed

4 files changed

+26
-10
lines changed

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/SSAConstruction.qll

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,9 +280,18 @@ cached private module Cached {
280280

281281
cached Instruction getInstructionBackEdgeSuccessor(Instruction instruction, EdgeKind kind) {
282282
exists(OldInstruction oldInstruction |
283-
oldInstruction = getOldInstruction(instruction) and
284-
result = getNewInstruction(oldInstruction.getBackEdgeSuccessor(kind)) and
285-
not Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind)
283+
not Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind) and
284+
// There is only one case for the translation into `result` because the
285+
// SSA construction never inserts extra instructions _before_ an existing
286+
// instruction.
287+
getOldInstruction(result) = oldInstruction.getBackEdgeSuccessor(kind) and
288+
// There are two cases for the translation into `instruction` because the
289+
// SSA construction might have inserted a chi node _after_
290+
// `oldInstruction`, in which case the back edge should come out of the
291+
// chi node instead.
292+
if hasChiNode(_, oldInstruction)
293+
then instruction = getChiInstruction(oldInstruction)
294+
else instruction = getNewInstruction(oldInstruction)
286295
)
287296
}
288297

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/SSAConstruction.qll

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -280,9 +280,18 @@ cached private module Cached {
280280

281281
cached Instruction getInstructionBackEdgeSuccessor(Instruction instruction, EdgeKind kind) {
282282
exists(OldInstruction oldInstruction |
283-
oldInstruction = getOldInstruction(instruction) and
284-
result = getNewInstruction(oldInstruction.getBackEdgeSuccessor(kind)) and
285-
not Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind)
283+
not Reachability::isInfeasibleInstructionSuccessor(oldInstruction, kind) and
284+
// There is only one case for the translation into `result` because the
285+
// SSA construction never inserts extra instructions _before_ an existing
286+
// instruction.
287+
getOldInstruction(result) = oldInstruction.getBackEdgeSuccessor(kind) and
288+
// There are two cases for the translation into `instruction` because the
289+
// SSA construction might have inserted a chi node _after_
290+
// `oldInstruction`, in which case the back edge should come out of the
291+
// chi node instead.
292+
if hasChiNode(_, oldInstruction)
293+
then instruction = getChiInstruction(oldInstruction)
294+
else instruction = getNewInstruction(oldInstruction)
286295
)
287296
}
288297

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4687,5 +4687,5 @@ ir.cpp:
46874687
# 1059| r3_8(int) = Constant[0] :
46884688
# 1059| r3_9(bool) = CompareGT : r3_4, r3_8
46894689
# 1059| v3_10(void) = ConditionalBranch : r3_9
4690-
#-----| False (back edge) -> Block 2
4691-
#-----| True (back edge) -> Block 1
4690+
#-----| False -> Block 2
4691+
#-----| True -> Block 1

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,4 @@ operandAcrossFunctions
88
instructionWithoutUniqueBlock
99
containsLoopOfForwardEdges
1010
lostReachability
11-
| ir.cpp:1060:12:1060:12 | Constant: (char)... |
12-
| ir.cpp:1061:1:1061:1 | NoOp: return ... |
1311
backEdgeCountMismatch

0 commit comments

Comments
 (0)