@@ -1214,7 +1214,7 @@ private module GetConvertedResultExpression {
12141214 // represents the extent.
12151215 exists ( TranslatedNonConstantAllocationSize tas |
12161216 result = tas .getExtent ( ) .getExpr ( ) and
1217- instr = tas .getInstruction ( any ( AllocationExtentConvertTag tag ) )
1217+ instr = tas .getInstruction ( AllocationExtentConvertTag ( ) )
12181218 )
12191219 or
12201220 // There's no instruction that returns `ParenthesisExpr`, but some queries
@@ -1223,6 +1223,39 @@ private module GetConvertedResultExpression {
12231223 result = ttc .getExpr ( ) .( ParenthesisExpr ) and
12241224 instr = ttc .getResult ( )
12251225 )
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+ )
12261259 }
12271260
12281261 private Expr getConvertedResultExpressionImpl ( Instruction instr ) {
@@ -1242,15 +1275,15 @@ private module GetConvertedResultExpression {
12421275 // `StoreInstruction` contains the result of the expression even though
12431276 // this isn't totally aligned with the C/C++ standard.
12441277 exists ( TranslatedAssignOperation tao |
1245- store = tao .getInstruction ( any ( AssignmentStoreTag tag ) ) and
1278+ store = tao .getInstruction ( AssignmentStoreTag ( ) ) and
12461279 result = tao .getExpr ( )
12471280 )
12481281 or
12491282 // Similarly for `i++` and `++i` we pretend that the generated
12501283 // `StoreInstruction` is contains the result of the expression even though
12511284 // this isn't totally aligned with the C/C++ standard.
12521285 exists ( TranslatedCrementOperation tco |
1253- store = tco .getInstruction ( any ( CrementStoreTag tag ) ) and
1286+ store = tco .getInstruction ( CrementStoreTag ( ) ) and
12541287 result = tco .getExpr ( )
12551288 )
12561289 }
@@ -2065,12 +2098,7 @@ module ExprFlowCached {
20652098 isIndirectBaseOfArrayAccess ( n , result )
20662099 or
20672100 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 ( )
20742102 }
20752103
20762104 /**
0 commit comments