@@ -122,7 +122,46 @@ abstract private class OperandBasedUse extends UseImpl {
122
122
override string toString ( ) { result = operand .toString ( ) }
123
123
124
124
final override predicate hasIndexInBlock ( IRBlock block , int index ) {
125
- operand .getUse ( ) = block .getInstruction ( index )
125
+ // Ideally, this would just be implemented as:
126
+ // ```
127
+ // operand.getUse() = block.getInstruction(index)
128
+ // ```
129
+ // but because the IR generated for a snippet such as
130
+ // ```
131
+ // int x = *p++;
132
+ // ```
133
+ // looks like
134
+ // ```
135
+ // r1(glval<int>) = VariableAddress[x] :
136
+ // r2(glval<int *>) = VariableAddress[p] :
137
+ // r3(int *) = Load[p] : &:r2, m1
138
+ // r4(int) = Constant[1] :
139
+ // r5(int *) = PointerAdd[4] : r3, r4
140
+ // m3(int *) = Store[p] : &:r2, r5
141
+ // r6(int *) = CopyValue : r3
142
+ // r7(int) = Load[?] : &:r6, ~m2
143
+ // m2(int) = Store[x] : &:r1, r7
144
+ // ```
145
+ // we need to ensure that the `r3` operand of the `CopyValue` instruction isn't seen as a fresh use
146
+ // of `p` that happens after the increment. So if the base instruction of this use comes from a
147
+ // post-fix crement operation we set the index of the SSA use that wraps the `r3` operand at the
148
+ // `CopyValue` instruction to be the same index as the `r3` operand at the `PointerAdd` instruction.
149
+ // This ensures that the SSA library doesn't create flow from the `PointerAdd` to `r6`.
150
+ exists ( BaseSourceVariableInstruction base | base = this .getBase ( ) |
151
+ if base .getAst ( ) = any ( Cpp:: PostfixCrementOperation c ) .getOperand ( )
152
+ then
153
+ exists ( Operand op |
154
+ op =
155
+ min ( Operand cand , int i |
156
+ isUse ( _, cand , base , _, _) and
157
+ block .getInstruction ( i ) = cand .getUse ( )
158
+ |
159
+ cand order by i
160
+ ) and
161
+ block .getInstruction ( index ) = op .getUse ( )
162
+ )
163
+ else operand .getUse ( ) = block .getInstruction ( index )
164
+ )
126
165
}
127
166
128
167
final override Cpp:: Location getLocation ( ) { result = operand .getLocation ( ) }
0 commit comments