Skip to content

Commit dbb4167

Browse files
authored
Merge pull request github#14579 from jketema/ir-backwards
C++: Define an extractor version table and use in IR generation
2 parents b1d4ca5 + 6400492 commit dbb4167

File tree

11 files changed

+9769
-724
lines changed

11 files changed

+9769
-724
lines changed

cpp/downgrades/f79ce79e3b751aeeed59e594633ba5c07a27ef3e/old.dbscheme

Lines changed: 2226 additions & 0 deletions
Large diffs are not rendered by default.

cpp/downgrades/f79ce79e3b751aeeed59e594633ba5c07a27ef3e/semmlecode.cpp.dbscheme

Lines changed: 2221 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
description: Introduce extractor version numbers
2+
compatibility: breaking
3+
extractor_version.rel: delete
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* INTERNAL: Do not use. Provides predicates for getting the CodeQL and frontend
3+
* version used during database extraction.
4+
*/
5+
6+
/** Get the extractor CodeQL version */
7+
string getExtractorCodeQLVersion() { extractor_version(result, _) }
8+
9+
/** Get the extractor frontend version */
10+
string getExtractorFrontendVersion() { extractor_version(_, result) }
11+
12+
predicate isExtractorFrontendVersion65OrHigher() {
13+
// Version numbers we not included in the database before 6.5.
14+
exists(getExtractorCodeQLVersion())
15+
}

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
private import cpp
22
import semmle.code.cpp.ir.implementation.raw.IR
3+
private import semmle.code.cpp.internal.ExtractorVersion
34
private import semmle.code.cpp.ir.IRConfiguration
45
private import semmle.code.cpp.ir.implementation.Opcode
56
private import semmle.code.cpp.ir.implementation.internal.OperandTag
@@ -362,10 +363,10 @@ predicate ignoreLoad(Expr expr) {
362363
expr instanceof FunctionAccess
363364
or
364365
// The load is duplicated from the operand.
365-
expr instanceof ParenthesisExpr
366+
isExtractorFrontendVersion65OrHigher() and expr instanceof ParenthesisExpr
366367
or
367368
// The load is duplicated from the right operand.
368-
expr instanceof CommaExpr
369+
isExtractorFrontendVersion65OrHigher() and expr instanceof CommaExpr
369370
or
370371
expr.(PointerDereferenceExpr).getOperand().getFullyConverted().getType().getUnspecifiedType()
371372
instanceof FunctionPointerType

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll

Lines changed: 73 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
private import cpp
2+
private import semmle.code.cpp.internal.ExtractorVersion
23
private import semmle.code.cpp.ir.implementation.IRType
34
private import semmle.code.cpp.ir.implementation.Opcode
45
private import semmle.code.cpp.ir.implementation.internal.OperandTag
@@ -648,7 +649,21 @@ abstract class TranslatedCrementOperation extends TranslatedNonConstantExpr {
648649
class 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 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+
}
652667
}
653668

654669
class 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 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+
}
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 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+
}
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 isExtractorFrontendVersion65OrHigher()
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 isExtractorFrontendVersion65OrHigher()) 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 isExtractorFrontendVersion65OrHigher()
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 isExtractorFrontendVersion65OrHigher()) 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 isExtractorFrontendVersion65OrHigher()) 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 isExtractorFrontendVersion65OrHigher()
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 isExtractorFrontendVersion65OrHigher()
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+
isExtractorFrontendVersion65OrHigher()
3281+
)
32303282
or
3231-
expr instanceof PrefixCrementOperation
3283+
expr instanceof PrefixCrementOperation and
3284+
(
3285+
not expr.isPRValueCategory() // is C++
3286+
or
3287+
isExtractorFrontendVersion65OrHigher()
3288+
)
32323289
or
32333290
// Because the load is on the `e` in `e++`.
32343291
expr instanceof PostfixCrementOperation

cpp/ql/lib/semmlecode.cpp.dbscheme

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,11 @@ svnchurn(
197197
* C++ dbscheme
198198
*/
199199

200+
extractor_version(
201+
string codeql_version: string ref,
202+
string frontend_version: string ref
203+
)
204+
200205
@location = @location_stmt | @location_expr | @location_default ;
201206

202207
/**

0 commit comments

Comments
 (0)