1
1
private import cpp
2
+ private import semmle.code.cpp.internal.ExtractorVersion
2
3
private import semmle.code.cpp.ir.implementation.IRType
3
4
private import semmle.code.cpp.ir.implementation.Opcode
4
5
private import semmle.code.cpp.ir.implementation.internal.OperandTag
@@ -648,7 +649,21 @@ abstract class TranslatedCrementOperation extends TranslatedNonConstantExpr {
648
649
class TranslatedPrefixCrementOperation extends TranslatedCrementOperation {
649
650
override PrefixCrementOperation expr ;
650
651
651
- override Instruction getResult ( ) { result = this .getUnloadedOperand ( ) .getResult ( ) }
652
+ override Instruction getResult ( ) {
653
+ // The following distinction is needed to work around extractor limitations
654
+ // in old versions of the extractor.
655
+ if expr .isPRValueCategory ( ) and not isExtractorFrontendVersion65OrHigher ( )
656
+ then
657
+ // If this is C, then the result of a prefix crement is a prvalue for the
658
+ // new value assigned to the operand. If this is C++, then the result is
659
+ // an lvalue, but that lvalue is being loaded as part of this expression.
660
+ // EDG doesn't mark this as a load.
661
+ result = this .getInstruction ( CrementOpTag ( ) )
662
+ else
663
+ // This is C++, where the result is an lvalue for the operand, and that
664
+ // lvalue is not being loaded as part of this expression.
665
+ result = this .getUnloadedOperand ( ) .getResult ( )
666
+ }
652
667
}
653
668
654
669
class TranslatedPostfixCrementOperation extends TranslatedCrementOperation {
@@ -1491,7 +1506,21 @@ class TranslatedAssignExpr extends TranslatedNonConstantExpr {
1491
1506
result = this .getRightOperand ( ) .getFirstInstruction ( )
1492
1507
}
1493
1508
1494
- final override Instruction getResult ( ) { result = this .getLeftOperand ( ) .getResult ( ) }
1509
+ final override Instruction getResult ( ) {
1510
+ // The following distinction is needed to work around extractor limitations
1511
+ // in old versions of the extractor.
1512
+ if expr .isPRValueCategory ( ) and not isExtractorFrontendVersion65OrHigher ( )
1513
+ then
1514
+ // If this is C, then the result of an assignment is a prvalue for the new
1515
+ // value assigned to the left operand. If this is C++, then the result is
1516
+ // an lvalue, but that lvalue is being loaded as part of this expression.
1517
+ // EDG doesn't mark this as a load.
1518
+ result = this .getRightOperand ( ) .getResult ( )
1519
+ else
1520
+ // This is C++, where the result is an lvalue for the left operand,
1521
+ // and that lvalue is not being loaded as part of this expression.
1522
+ result = this .getLeftOperand ( ) .getResult ( )
1523
+ }
1495
1524
1496
1525
final TranslatedExpr getLeftOperand ( ) {
1497
1526
result = getTranslatedExpr ( expr .getLValue ( ) .getFullyConverted ( ) )
@@ -1617,7 +1646,21 @@ class TranslatedAssignOperation extends TranslatedNonConstantExpr {
1617
1646
result = this .getRightOperand ( ) .getFirstInstruction ( )
1618
1647
}
1619
1648
1620
- final override Instruction getResult ( ) { result = this .getUnloadedLeftOperand ( ) .getResult ( ) }
1649
+ final override Instruction getResult ( ) {
1650
+ // The following distinction is needed to work around extractor limitations
1651
+ // in old versions of the extractor.
1652
+ if expr .isPRValueCategory ( ) and not isExtractorFrontendVersion65OrHigher ( )
1653
+ then
1654
+ // If this is C, then the result of an assignment is a prvalue for the new
1655
+ // value assigned to the left operand. If this is C++, then the result is
1656
+ // an lvalue, but that lvalue is being loaded as part of this expression.
1657
+ // EDG doesn't mark this as a load.
1658
+ result = this .getStoredValue ( )
1659
+ else
1660
+ // This is C++, where the result is an lvalue for the left operand,
1661
+ // and that lvalue is not being loaded as part of this expression.
1662
+ result = this .getUnloadedLeftOperand ( ) .getResult ( )
1663
+ }
1621
1664
1622
1665
final TranslatedExpr getUnloadedLeftOperand ( ) {
1623
1666
result = this .getLoadedLeftOperand ( ) .getOperand ( )
@@ -2155,15 +2198,16 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr {
2155
2198
not this .elseIsVoid ( ) and tag = ConditionValueFalseStoreTag ( )
2156
2199
) and
2157
2200
opcode instanceof Opcode:: Store and
2158
- (
2201
+ if isExtractorFrontendVersion65OrHigher ( )
2202
+ then
2159
2203
not expr .hasLValueToRValueConversion ( ) and
2160
2204
resultType = this .getResultType ( )
2161
2205
or
2162
2206
expr .hasLValueToRValueConversion ( ) and
2163
2207
resultType = getTypeForPRValue ( expr .getType ( ) )
2164
- )
2208
+ else resultType = this . getResultType ( )
2165
2209
or
2166
- not expr .hasLValueToRValueConversion ( ) and
2210
+ ( not expr .hasLValueToRValueConversion ( ) or not isExtractorFrontendVersion65OrHigher ( ) ) and
2167
2211
tag = ConditionValueResultLoadTag ( ) and
2168
2212
opcode instanceof Opcode:: Load and
2169
2213
resultType = this .getResultType ( )
@@ -2193,15 +2237,16 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr {
2193
2237
)
2194
2238
or
2195
2239
tag = ConditionValueResultTempAddressTag ( ) and
2196
- (
2240
+ if isExtractorFrontendVersion65OrHigher ( )
2241
+ then
2197
2242
not expr .hasLValueToRValueConversion ( ) and
2198
2243
result = this .getInstruction ( ConditionValueResultLoadTag ( ) )
2199
2244
or
2200
2245
expr .hasLValueToRValueConversion ( ) and
2201
2246
result = this .getParent ( ) .getChildSuccessor ( this )
2202
- )
2247
+ else result = this . getInstruction ( ConditionValueResultLoadTag ( ) )
2203
2248
or
2204
- not expr .hasLValueToRValueConversion ( ) and
2249
+ ( not expr .hasLValueToRValueConversion ( ) or not isExtractorFrontendVersion65OrHigher ( ) ) and
2205
2250
tag = ConditionValueResultLoadTag ( ) and
2206
2251
result = this .getParent ( ) .getChildSuccessor ( this )
2207
2252
)
@@ -2230,7 +2275,7 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr {
2230
2275
result = this .getElse ( ) .getResult ( )
2231
2276
)
2232
2277
or
2233
- not expr .hasLValueToRValueConversion ( ) and
2278
+ ( not expr .hasLValueToRValueConversion ( ) or not isExtractorFrontendVersion65OrHigher ( ) ) and
2234
2279
tag = ConditionValueResultLoadTag ( ) and
2235
2280
operandTag instanceof AddressOperandTag and
2236
2281
result = this .getInstruction ( ConditionValueResultTempAddressTag ( ) )
@@ -2240,13 +2285,14 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr {
2240
2285
final override predicate hasTempVariable ( TempVariableTag tag , CppType type ) {
2241
2286
not this .resultIsVoid ( ) and
2242
2287
tag = ConditionValueTempVar ( ) and
2243
- (
2288
+ if isExtractorFrontendVersion65OrHigher ( )
2289
+ then
2244
2290
not expr .hasLValueToRValueConversion ( ) and
2245
2291
type = this .getResultType ( )
2246
2292
or
2247
2293
expr .hasLValueToRValueConversion ( ) and
2248
2294
type = getTypeForPRValue ( expr .getType ( ) )
2249
- )
2295
+ else type = this . getResultType ( )
2250
2296
}
2251
2297
2252
2298
final override IRVariable getInstructionVariable ( InstructionTag tag ) {
@@ -2261,13 +2307,14 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr {
2261
2307
2262
2308
final override Instruction getResult ( ) {
2263
2309
not this .resultIsVoid ( ) and
2264
- (
2310
+ if isExtractorFrontendVersion65OrHigher ( )
2311
+ then
2265
2312
expr .hasLValueToRValueConversion ( ) and
2266
2313
result = this .getInstruction ( ConditionValueResultTempAddressTag ( ) )
2267
2314
or
2268
2315
not expr .hasLValueToRValueConversion ( ) and
2269
2316
result = this .getInstruction ( ConditionValueResultLoadTag ( ) )
2270
- )
2317
+ else result = this . getInstruction ( ConditionValueResultLoadTag ( ) )
2271
2318
}
2272
2319
2273
2320
override Instruction getChildSuccessor ( TranslatedElement child ) {
@@ -3226,9 +3273,19 @@ predicate exprNeedsCopyIfNotLoaded(Expr expr) {
3226
3273
(
3227
3274
expr instanceof AssignExpr
3228
3275
or
3229
- expr instanceof AssignOperation
3276
+ expr instanceof AssignOperation and
3277
+ (
3278
+ not expr .isPRValueCategory ( ) // is C++
3279
+ or
3280
+ isExtractorFrontendVersion65OrHigher ( )
3281
+ )
3230
3282
or
3231
- expr instanceof PrefixCrementOperation
3283
+ expr instanceof PrefixCrementOperation and
3284
+ (
3285
+ not expr .isPRValueCategory ( ) // is C++
3286
+ or
3287
+ isExtractorFrontendVersion65OrHigher ( )
3288
+ )
3232
3289
or
3233
3290
// Because the load is on the `e` in `e++`.
3234
3291
expr instanceof PostfixCrementOperation
0 commit comments