11private import cpp
2+ private import semmle.code.cpp.internal.ExtractorVersion
23private import semmle.code.cpp.ir.implementation.IRType
34private import semmle.code.cpp.ir.implementation.Opcode
45private import semmle.code.cpp.ir.implementation.internal.OperandTag
@@ -648,7 +649,21 @@ abstract class TranslatedCrementOperation extends TranslatedNonConstantExpr {
648649class TranslatedPrefixCrementOperation extends TranslatedCrementOperation {
649650 override PrefixCrementOperation expr ;
650651
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 exists ( getExtractorFrontendVersion ( ) )
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+ }
652667}
653668
654669class TranslatedPostfixCrementOperation extends TranslatedCrementOperation {
@@ -1491,7 +1506,21 @@ class TranslatedAssignExpr extends TranslatedNonConstantExpr {
14911506 result = this .getRightOperand ( ) .getFirstInstruction ( )
14921507 }
14931508
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 exists ( getExtractorFrontendVersion ( ) )
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+ }
14951524
14961525 final TranslatedExpr getLeftOperand ( ) {
14971526 result = getTranslatedExpr ( expr .getLValue ( ) .getFullyConverted ( ) )
@@ -1617,7 +1646,21 @@ class TranslatedAssignOperation extends TranslatedNonConstantExpr {
16171646 result = this .getRightOperand ( ) .getFirstInstruction ( )
16181647 }
16191648
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 exists ( getExtractorFrontendVersion ( ) )
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+ }
16211664
16221665 final TranslatedExpr getUnloadedLeftOperand ( ) {
16231666 result = this .getLoadedLeftOperand ( ) .getOperand ( )
@@ -2155,15 +2198,16 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr {
21552198 not this .elseIsVoid ( ) and tag = ConditionValueFalseStoreTag ( )
21562199 ) and
21572200 opcode instanceof Opcode:: Store and
2158- (
2201+ if exists ( getExtractorFrontendVersion ( ) )
2202+ then
21592203 not expr .hasLValueToRValueConversion ( ) and
21602204 resultType = this .getResultType ( )
21612205 or
21622206 expr .hasLValueToRValueConversion ( ) and
21632207 resultType = getTypeForPRValue ( expr .getType ( ) )
2164- )
2208+ else resultType = this . getResultType ( )
21652209 or
2166- not expr .hasLValueToRValueConversion ( ) and
2210+ ( not expr .hasLValueToRValueConversion ( ) or not exists ( getExtractorFrontendVersion ( ) ) ) and
21672211 tag = ConditionValueResultLoadTag ( ) and
21682212 opcode instanceof Opcode:: Load and
21692213 resultType = this .getResultType ( )
@@ -2193,15 +2237,16 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr {
21932237 )
21942238 or
21952239 tag = ConditionValueResultTempAddressTag ( ) and
2196- (
2240+ if exists ( getExtractorFrontendVersion ( ) )
2241+ then
21972242 not expr .hasLValueToRValueConversion ( ) and
21982243 result = this .getInstruction ( ConditionValueResultLoadTag ( ) )
21992244 or
22002245 expr .hasLValueToRValueConversion ( ) and
22012246 result = this .getParent ( ) .getChildSuccessor ( this )
2202- )
2247+ else result = this . getInstruction ( ConditionValueResultLoadTag ( ) )
22032248 or
2204- not expr .hasLValueToRValueConversion ( ) and
2249+ ( not expr .hasLValueToRValueConversion ( ) or not exists ( getExtractorFrontendVersion ( ) ) ) and
22052250 tag = ConditionValueResultLoadTag ( ) and
22062251 result = this .getParent ( ) .getChildSuccessor ( this )
22072252 )
@@ -2230,7 +2275,7 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr {
22302275 result = this .getElse ( ) .getResult ( )
22312276 )
22322277 or
2233- not expr .hasLValueToRValueConversion ( ) and
2278+ ( not expr .hasLValueToRValueConversion ( ) or not exists ( getExtractorFrontendVersion ( ) ) ) and
22342279 tag = ConditionValueResultLoadTag ( ) and
22352280 operandTag instanceof AddressOperandTag and
22362281 result = this .getInstruction ( ConditionValueResultTempAddressTag ( ) )
@@ -2240,13 +2285,14 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr {
22402285 final override predicate hasTempVariable ( TempVariableTag tag , CppType type ) {
22412286 not this .resultIsVoid ( ) and
22422287 tag = ConditionValueTempVar ( ) and
2243- (
2288+ if exists ( getExtractorFrontendVersion ( ) )
2289+ then
22442290 not expr .hasLValueToRValueConversion ( ) and
22452291 type = this .getResultType ( )
22462292 or
22472293 expr .hasLValueToRValueConversion ( ) and
22482294 type = getTypeForPRValue ( expr .getType ( ) )
2249- )
2295+ else type = this . getResultType ( )
22502296 }
22512297
22522298 final override IRVariable getInstructionVariable ( InstructionTag tag ) {
@@ -2261,13 +2307,14 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr {
22612307
22622308 final override Instruction getResult ( ) {
22632309 not this .resultIsVoid ( ) and
2264- (
2310+ if exists ( getExtractorFrontendVersion ( ) )
2311+ then
22652312 expr .hasLValueToRValueConversion ( ) and
22662313 result = this .getInstruction ( ConditionValueResultTempAddressTag ( ) )
22672314 or
22682315 not expr .hasLValueToRValueConversion ( ) and
22692316 result = this .getInstruction ( ConditionValueResultLoadTag ( ) )
2270- )
2317+ else result = this . getInstruction ( ConditionValueResultLoadTag ( ) )
22712318 }
22722319
22732320 override Instruction getChildSuccessor ( TranslatedElement child ) {
@@ -3226,9 +3273,19 @@ predicate exprNeedsCopyIfNotLoaded(Expr expr) {
32263273 (
32273274 expr instanceof AssignExpr
32283275 or
3229- expr instanceof AssignOperation
3276+ expr instanceof AssignOperation and
3277+ (
3278+ not expr .isPRValueCategory ( ) // is C++
3279+ or
3280+ exists ( getExtractorFrontendVersion ( ) )
3281+ )
32303282 or
3231- expr instanceof PrefixCrementOperation
3283+ expr instanceof PrefixCrementOperation and
3284+ (
3285+ not expr .isPRValueCategory ( ) // is C++
3286+ or
3287+ exists ( getExtractorFrontendVersion ( ) )
3288+ )
32323289 or
32333290 // Because the load is on the `e` in `e++`.
32343291 expr instanceof PostfixCrementOperation
0 commit comments