Skip to content

Commit fc85ef7

Browse files
committed
C++: Introduce 'PseudoDeclarationEntry's to handle missing 'DeclarationEntry's during IR construction.
1 parent 2da46ad commit fc85ef7

File tree

7 files changed

+123
-26
lines changed

7 files changed

+123
-26
lines changed

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

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ private import TranslatedInitialization
1313
* Gets the `TranslatedDeclarationEntry` that represents the declaration
1414
* `entry`.
1515
*/
16-
TranslatedDeclarationEntry getTranslatedDeclarationEntry(DeclarationEntry entry) {
17-
result.getAst() = entry
16+
TranslatedDeclarationEntry getTranslatedDeclarationEntry(PseudoDeclarationEntry entry) {
17+
result.getPseudoDeclarationEntry() = entry
1818
}
1919

2020
/**
@@ -24,20 +24,22 @@ TranslatedDeclarationEntry getTranslatedDeclarationEntry(DeclarationEntry entry)
2424
* functions do not have a `TranslatedDeclarationEntry`.
2525
*/
2626
abstract class TranslatedDeclarationEntry extends TranslatedElement, TTranslatedDeclarationEntry {
27-
DeclarationEntry entry;
27+
PseudoDeclarationEntry entry;
2828

2929
TranslatedDeclarationEntry() { this = TTranslatedDeclarationEntry(entry) }
3030

3131
final override Function getFunction() {
3232
exists(DeclStmt stmt |
33-
stmt.getADeclarationEntry() = entry and
33+
stmt = entry.getStmt() and
3434
result = stmt.getEnclosingFunction()
3535
)
3636
}
3737

38+
PseudoDeclarationEntry getPseudoDeclarationEntry() { result = entry }
39+
3840
final override string toString() { result = entry.toString() }
3941

40-
final override Locatable getAst() { result = entry }
42+
final override Locatable getAst() { result = entry.getAst() }
4143

4244
/** DEPRECATED: Alias for getAst */
4345
deprecated override Locatable getAST() { result = getAst() }
@@ -216,7 +218,7 @@ class TranslatedStaticLocalVariableDeclarationEntry extends TranslatedDeclaratio
216218
*/
217219
class TranslatedStaticLocalVariableInitialization extends TranslatedElement,
218220
TranslatedLocalVariableDeclaration, TTranslatedStaticLocalVariableInitialization {
219-
VariableDeclarationEntry entry;
221+
PseudoVariableDeclarationEntry entry;
220222
StaticLocalVariable var;
221223

222224
TranslatedStaticLocalVariableInitialization() {
@@ -226,7 +228,7 @@ class TranslatedStaticLocalVariableInitialization extends TranslatedElement,
226228

227229
final override string toString() { result = "init: " + entry.toString() }
228230

229-
final override Locatable getAst() { result = entry }
231+
final override Locatable getAst() { result = entry.getAst() }
230232

231233
/** DEPRECATED: Alias for getAst */
232234
deprecated override Locatable getAST() { result = getAst() }

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

Lines changed: 98 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -443,10 +443,10 @@ predicate hasTranslatedSyntheticTemporaryObject(Expr expr) {
443443
* necessary for automatic local variables, or for static local variables with dynamic
444444
* initialization.
445445
*/
446-
private predicate translateDeclarationEntry(DeclarationEntry entry) {
446+
private predicate translateDeclarationEntry(PseudoDeclarationEntry entry) {
447447
exists(DeclStmt declStmt, LocalVariable var |
448448
translateStmt(declStmt) and
449-
declStmt.getADeclarationEntry() = entry and
449+
declStmt = entry.getStmt() and
450450
// Only declarations of local variables need to be translated to IR.
451451
var = entry.getDeclaration() and
452452
(
@@ -458,6 +458,100 @@ private predicate translateDeclarationEntry(DeclarationEntry entry) {
458458
)
459459
}
460460

461+
private module PseudoDeclarationEntries {
462+
private newtype TPseudoDeclarationEntry =
463+
TPresentDeclarationEntry(DeclarationEntry entry) or
464+
TMissingDeclarationEntry(DeclStmt stmt, Declaration d, int index) {
465+
not exists(stmt.getDeclarationEntry(index)) and
466+
stmt.getDeclaration(index) = d
467+
}
468+
469+
/**
470+
* An entity that represents a declaration entry in the database.
471+
*
472+
* This class exists to work around the fact that `DeclStmt`s in
473+
* template instantiations do not have `DeclarationEntry`s.
474+
*
475+
* So instead, the IR works with `PseudoDeclarationEntry`s that synthesize
476+
* missing `DeclarationEntry`s when there is no result for `DeclStmt::getDeclarationEntry`.
477+
*/
478+
abstract class PseudoDeclarationEntry extends TPseudoDeclarationEntry {
479+
/** Gets a string representation of this `PseudoDeclarationEntry`. */
480+
abstract string toString();
481+
482+
/** Gets the `DeclStmt` that this `PseudoDeclarationEntry` belongs to. */
483+
abstract DeclStmt getStmt();
484+
485+
/** Gets the `Declaration` declared by this `PseudoDeclarationEntry`. */
486+
abstract Declaration getDeclaration();
487+
488+
/** Gets the AST represented by this `PseudoDeclarationEntry`. */
489+
abstract Locatable getAst();
490+
491+
/**
492+
* Holds if this `PseudoDeclarationEntry` is the `index`'th entry
493+
* declared by the enclosing `DeclStmt`.
494+
*/
495+
abstract predicate hasIndex(int index);
496+
}
497+
498+
/** A `PseudoDeclarationEntry` for an existing `DeclarationEntry`. */
499+
private class PresentDeclarationEntry extends PseudoDeclarationEntry, TPresentDeclarationEntry {
500+
DeclarationEntry entry;
501+
502+
PresentDeclarationEntry() { this = TPresentDeclarationEntry(entry) }
503+
504+
override string toString() { result = entry.toString() }
505+
506+
override DeclStmt getStmt() { result.getADeclarationEntry() = entry }
507+
508+
override Declaration getDeclaration() { result = entry.getDeclaration() }
509+
510+
override Locatable getAst() { result = entry }
511+
512+
override predicate hasIndex(int index) { this.getStmt().getDeclarationEntry(index) = entry }
513+
}
514+
515+
/**
516+
* A synthesized `DeclarationEntry` that is created when a `DeclStmt` is missing a
517+
* result for `DeclStmt::getDeclarationEntry`
518+
*/
519+
private class MissingDeclarationEntry extends PseudoDeclarationEntry, TMissingDeclarationEntry {
520+
DeclStmt stmt;
521+
Declaration d;
522+
int index;
523+
524+
MissingDeclarationEntry() { this = TMissingDeclarationEntry(stmt, d, index) }
525+
526+
override string toString() { result = "pseudo declaration of " + d.getName() }
527+
528+
override DeclStmt getStmt() { result = stmt }
529+
530+
override Declaration getDeclaration() { result = d }
531+
532+
override Locatable getAst() { result = stmt }
533+
534+
override predicate hasIndex(int idx) { idx = index }
535+
}
536+
537+
/** A `PseudoDeclarationEntry` that represents an entry for a `Variable`. */
538+
class PseudoVariableDeclarationEntry instanceof PseudoDeclarationEntry {
539+
Variable v;
540+
541+
PseudoVariableDeclarationEntry() { super.getDeclaration() = v }
542+
543+
Variable getDeclaration() { result = v }
544+
545+
string toString() { result = super.toString() }
546+
547+
Locatable getAst() { result = super.getAst() }
548+
549+
DeclStmt getStmt() { result = super.getStmt() }
550+
}
551+
}
552+
553+
import PseudoDeclarationEntries
554+
461555
newtype TTranslatedElement =
462556
// An expression that is not being consumed as a condition
463557
TTranslatedValueExpr(Expr expr) {
@@ -613,10 +707,10 @@ newtype TTranslatedElement =
613707
)
614708
} or
615709
// A local declaration
616-
TTranslatedDeclarationEntry(DeclarationEntry entry) { translateDeclarationEntry(entry) } or
710+
TTranslatedDeclarationEntry(PseudoDeclarationEntry entry) { translateDeclarationEntry(entry) } or
617711
// The dynamic initialization of a static local variable. This is a separate object from the
618712
// declaration entry.
619-
TTranslatedStaticLocalVariableInitialization(DeclarationEntry entry) {
713+
TTranslatedStaticLocalVariableInitialization(PseudoDeclarationEntry entry) {
620714
translateDeclarationEntry(entry) and
621715
entry.getDeclaration() instanceof StaticLocalVariable
622716
} or

cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ unexpectedOperand
33
duplicateOperand
44
missingPhiOperand
55
missingOperandType
6-
| ir.cpp:1877:13:1877:19 | ChiTotal | Operand 'ChiTotal' of instruction 'Chi' is missing a type in function '$@'. | ir.cpp:1875:13:1875:13 | int missing_declaration_entries::Bar2<int>::two_missing_variable_declaration_entries() | int missing_declaration_entries::Bar2<int>::two_missing_variable_declaration_entries() |
7-
| ir.cpp:1878:13:1878:19 | ChiTotal | Operand 'ChiTotal' of instruction 'Chi' is missing a type in function '$@'. | ir.cpp:1875:13:1875:13 | int missing_declaration_entries::Bar2<int>::two_missing_variable_declaration_entries() | int missing_declaration_entries::Bar2<int>::two_missing_variable_declaration_entries() |
86
duplicateChiOperand
97
sideEffectWithoutPrimary
108
instructionWithoutSuccessor

cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ unexpectedOperand
33
duplicateOperand
44
missingPhiOperand
55
missingOperandType
6-
| ir.cpp:1877:13:1877:19 | ChiTotal | Operand 'ChiTotal' of instruction 'Chi' is missing a type in function '$@'. | ir.cpp:1875:13:1875:13 | int missing_declaration_entries::Bar2<int>::two_missing_variable_declaration_entries() | int missing_declaration_entries::Bar2<int>::two_missing_variable_declaration_entries() |
7-
| ir.cpp:1878:13:1878:19 | ChiTotal | Operand 'ChiTotal' of instruction 'Chi' is missing a type in function '$@'. | ir.cpp:1875:13:1875:13 | int missing_declaration_entries::Bar2<int>::two_missing_variable_declaration_entries() | int missing_declaration_entries::Bar2<int>::two_missing_variable_declaration_entries() |
86
duplicateChiOperand
97
sideEffectWithoutPrimary
108
instructionWithoutSuccessor

cpp/ql/test/library-tests/ir/ir/operand_locations.expected

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5303,10 +5303,10 @@
53035303
| ir.cpp:1077:39:1077:39 | Address | &:r1077_7 |
53045304
| ir.cpp:1077:39:1077:39 | Load | m1077_6 |
53055305
| ir.cpp:1077:39:1077:39 | SideEffect | m1077_8 |
5306-
| ir.cpp:1078:5:1078:5 | Address | &:r1078_1 |
5307-
| ir.cpp:1078:5:1078:5 | Address | &:r1078_7 |
5308-
| ir.cpp:1078:5:1078:5 | Address | &:r1078_15 |
5309-
| ir.cpp:1078:14:1078:14 | Address | &:r1078_33 |
5306+
| ir.cpp:1078:5:1082:5 | Address | &:r1078_1 |
5307+
| ir.cpp:1078:5:1082:5 | Address | &:r1078_7 |
5308+
| ir.cpp:1078:5:1082:5 | Address | &:r1078_15 |
5309+
| ir.cpp:1078:5:1082:5 | Address | &:r1078_33 |
53105310
| ir.cpp:1078:18:1078:18 | Address | &:r1078_2 |
53115311
| ir.cpp:1078:18:1078:18 | Address | &:r1078_8 |
53125312
| ir.cpp:1078:18:1078:18 | Address | &:r1078_16 |
@@ -5369,10 +5369,10 @@
53695369
| ir.cpp:1079:13:1079:13 | Load | m1078_40 |
53705370
| ir.cpp:1079:13:1079:17 | Condition | r1079_4 |
53715371
| ir.cpp:1079:17:1079:17 | Right | r1079_3 |
5372-
| ir.cpp:1084:5:1084:5 | Address | &:r1084_1 |
5373-
| ir.cpp:1084:5:1084:5 | Address | &:r1084_7 |
5374-
| ir.cpp:1084:5:1084:5 | Address | &:r1084_15 |
5375-
| ir.cpp:1084:21:1084:21 | Address | &:r1084_42 |
5372+
| ir.cpp:1084:5:1088:5 | Address | &:r1084_1 |
5373+
| ir.cpp:1084:5:1088:5 | Address | &:r1084_7 |
5374+
| ir.cpp:1084:5:1088:5 | Address | &:r1084_15 |
5375+
| ir.cpp:1084:5:1088:5 | Address | &:r1084_42 |
53765376
| ir.cpp:1084:25:1084:25 | Address | &:r1084_2 |
53775377
| ir.cpp:1084:25:1084:25 | Address | &:r1084_8 |
53785378
| ir.cpp:1084:25:1084:25 | Address | &:r1084_16 |
@@ -8703,15 +8703,17 @@
87038703
| ir.cpp:1875:13:1875:13 | Load | m1879_9 |
87048704
| ir.cpp:1875:13:1875:13 | SideEffect | m1875_3 |
87058705
| ir.cpp:1875:13:1875:13 | SideEffect | m1875_8 |
8706+
| ir.cpp:1876:13:1876:29 | Address | &:r1876_1 |
8707+
| ir.cpp:1876:13:1876:29 | Address | &:r1876_3 |
87068708
| ir.cpp:1877:13:1877:14 | Address | &:r1877_4 |
87078709
| ir.cpp:1877:13:1877:19 | ChiPartial | partial:m1877_5 |
8708-
| ir.cpp:1877:13:1877:19 | ChiTotal | total:~m? |
8710+
| ir.cpp:1877:13:1877:19 | ChiTotal | total:m1876_2 |
87098711
| ir.cpp:1877:14:1877:14 | Unary | r1877_2 |
87108712
| ir.cpp:1877:14:1877:14 | Unary | r1877_3 |
87118713
| ir.cpp:1877:18:1877:19 | StoreValue | r1877_1 |
87128714
| ir.cpp:1878:13:1878:14 | Address | &:r1878_4 |
87138715
| ir.cpp:1878:13:1878:19 | ChiPartial | partial:m1878_5 |
8714-
| ir.cpp:1878:13:1878:19 | ChiTotal | total:~m? |
8716+
| ir.cpp:1878:13:1878:19 | ChiTotal | total:m1876_4 |
87158717
| ir.cpp:1878:14:1878:14 | Unary | r1878_2 |
87168718
| ir.cpp:1878:14:1878:14 | Unary | r1878_3 |
87178719
| ir.cpp:1878:18:1878:19 | StoreValue | r1878_1 |

cpp/ql/test/library-tests/ir/ir/raw_consistency.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ missingOperandType
66
duplicateChiOperand
77
sideEffectWithoutPrimary
88
instructionWithoutSuccessor
9-
| ../../../include/memory.h:68:25:68:33 | CopyValue: (reference to) | Instruction 'CopyValue: (reference to)' has no successors in function '$@'. | ../../../include/memory.h:67:5:67:5 | void std::unique_ptr<int, std::default_delete<int>>::~unique_ptr() | void std::unique_ptr<int, std::default_delete<int>>::~unique_ptr() |
109
ambiguousSuccessors
1110
unexplainedLoop
1211
unnecessaryPhiInstruction

cpp/ql/test/library-tests/ir/ir/raw_ir.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9987,6 +9987,10 @@ ir.cpp:
99879987
# 1875| mu1875_5(glval<Bar2<int>>) = InitializeParameter[#this] : &:r1875_4
99889988
# 1875| r1875_6(glval<Bar2<int>>) = Load[#this] : &:r1875_4, ~m?
99899989
# 1875| mu1875_7(Bar2<int>) = InitializeIndirection[#this] : &:r1875_6
9990+
# 1876| r1876_1(glval<int[10]>) = VariableAddress[x] :
9991+
# 1876| mu1876_2(int[10]) = Uninitialized[x] : &:r1876_1
9992+
# 1876| r1876_3(glval<int[10]>) = VariableAddress[y] :
9993+
# 1876| mu1876_4(int[10]) = Uninitialized[y] : &:r1876_3
99909994
# 1877| r1877_1(int) = Constant[10] :
99919995
# 1877| r1877_2(glval<int[10]>) = VariableAddress[x] :
99929996
# 1877| r1877_3(int *) = Convert : r1877_2

0 commit comments

Comments
 (0)