Skip to content

Commit cc4c780

Browse files
authored
Merge pull request #2860 from jbj/isInCycle-neighbors
C++: Manual magic for `isInCycle`
2 parents aaf6926 + 0d239e8 commit cc4c780

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,19 @@ private module Cached {
102102
result = getMemoryOperandDefinition(instr, _, _)
103103
}
104104

105+
/**
106+
* Gets a non-phi instruction that defines an operand of `instr` but only if
107+
* both `instr` and the result have neighbor on the other side of the edge
108+
* between them. This is a necessary condition for being in a cycle, and it
109+
* removes about two thirds of the tuples that would otherwise be in this
110+
* predicate.
111+
*/
112+
private Instruction getNonPhiOperandDefOfIntermediate(Instruction instr) {
113+
result = getNonPhiOperandDef(instr) and
114+
exists(getNonPhiOperandDef(result)) and
115+
instr = getNonPhiOperandDef(_)
116+
}
117+
105118
/**
106119
* Holds if `instr` is part of a cycle in the operand graph that doesn't go
107120
* through a phi instruction and therefore should be impossible.
@@ -115,7 +128,7 @@ private module Cached {
115128
cached
116129
predicate isInCycle(Instruction instr) {
117130
instr instanceof Instruction and
118-
getNonPhiOperandDef+(instr) = instr
131+
getNonPhiOperandDefOfIntermediate+(instr) = instr
119132
}
120133

121134
cached

0 commit comments

Comments
 (0)