@@ -1214,7 +1214,7 @@ private module GetConvertedResultExpression {
1214
1214
// represents the extent.
1215
1215
exists ( TranslatedNonConstantAllocationSize tas |
1216
1216
result = tas .getExtent ( ) .getExpr ( ) and
1217
- instr = tas .getInstruction ( any ( AllocationExtentConvertTag tag ) )
1217
+ instr = tas .getInstruction ( AllocationExtentConvertTag ( ) )
1218
1218
)
1219
1219
or
1220
1220
// There's no instruction that returns `ParenthesisExpr`, but some queries
@@ -1223,6 +1223,39 @@ private module GetConvertedResultExpression {
1223
1223
result = ttc .getExpr ( ) .( ParenthesisExpr ) and
1224
1224
instr = ttc .getResult ( )
1225
1225
)
1226
+ or
1227
+ // Certain expressions generate `CopyValueInstruction`s only when they
1228
+ // are needed. Examples of this include crement operations and compound
1229
+ // assignment operations. For example:
1230
+ // ```cpp
1231
+ // int x = ...
1232
+ // int y = x++;
1233
+ // ```
1234
+ // this generate IR like:
1235
+ // ```
1236
+ // r1(glval<int>) = VariableAddress[x] :
1237
+ // r2(int) = Constant[0] :
1238
+ // m3(int) = Store[x] : &:r1, r2
1239
+ // r4(glval<int>) = VariableAddress[y] :
1240
+ // r5(glval<int>) = VariableAddress[x] :
1241
+ // r6(int) = Load[x] : &:r5, m3
1242
+ // r7(int) = Constant[1] :
1243
+ // r8(int) = Add : r6, r7
1244
+ // m9(int) = Store[x] : &:r5, r8
1245
+ // r11(int) = CopyValue : r6
1246
+ // m12(int) = Store[y] : &:r4, r11
1247
+ // ```
1248
+ // When the `CopyValueInstruction` is not generated there is no instruction
1249
+ // whose `getConvertedResultExpression` maps back to the expression. When
1250
+ // such an instruction doesn't exist it means that the old value is not
1251
+ // needed, and in that case the only value that will propagate forward in
1252
+ // the program is the value that's been updated. So in those cases we just
1253
+ // use the result of `node.asDefinition()` as the result of `node.asExpr()`.
1254
+ exists ( TranslatedCoreExpr tco |
1255
+ tco .getInstruction ( _) = instr and
1256
+ tco .producesExprResult ( ) and
1257
+ result = asDefinitionImpl0 ( instr )
1258
+ )
1226
1259
}
1227
1260
1228
1261
private Expr getConvertedResultExpressionImpl ( Instruction instr ) {
@@ -1242,15 +1275,15 @@ private module GetConvertedResultExpression {
1242
1275
// `StoreInstruction` contains the result of the expression even though
1243
1276
// this isn't totally aligned with the C/C++ standard.
1244
1277
exists ( TranslatedAssignOperation tao |
1245
- store = tao .getInstruction ( any ( AssignmentStoreTag tag ) ) and
1278
+ store = tao .getInstruction ( AssignmentStoreTag ( ) ) and
1246
1279
result = tao .getExpr ( )
1247
1280
)
1248
1281
or
1249
1282
// Similarly for `i++` and `++i` we pretend that the generated
1250
1283
// `StoreInstruction` is contains the result of the expression even though
1251
1284
// this isn't totally aligned with the C/C++ standard.
1252
1285
exists ( TranslatedCrementOperation tco |
1253
- store = tco .getInstruction ( any ( CrementStoreTag tag ) ) and
1286
+ store = tco .getInstruction ( CrementStoreTag ( ) ) and
1254
1287
result = tco .getExpr ( )
1255
1288
)
1256
1289
}
@@ -2065,12 +2098,7 @@ module ExprFlowCached {
2065
2098
isIndirectBaseOfArrayAccess ( n , result )
2066
2099
or
2067
2100
not isIndirectBaseOfArrayAccess ( n , _) and
2068
- (
2069
- result = n .asExpr ( )
2070
- or
2071
- result = n .asDefinition ( ) and
2072
- ( result instanceof CrementOperation or result instanceof AssignOperation )
2073
- )
2101
+ result = n .asExpr ( )
2074
2102
}
2075
2103
2076
2104
/**
0 commit comments