mirror of
https://github.com/github/codeql.git
synced 2026-04-29 18:55:14 +02:00
C++: Introduce 'PseudoDeclarationEntry's to handle missing 'DeclarationEntry's during IR construction.
This commit is contained in:
@@ -13,8 +13,8 @@ private import TranslatedInitialization
|
||||
* Gets the `TranslatedDeclarationEntry` that represents the declaration
|
||||
* `entry`.
|
||||
*/
|
||||
TranslatedDeclarationEntry getTranslatedDeclarationEntry(DeclarationEntry entry) {
|
||||
result.getAst() = entry
|
||||
TranslatedDeclarationEntry getTranslatedDeclarationEntry(PseudoDeclarationEntry entry) {
|
||||
result.getPseudoDeclarationEntry() = entry
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -24,20 +24,22 @@ TranslatedDeclarationEntry getTranslatedDeclarationEntry(DeclarationEntry entry)
|
||||
* functions do not have a `TranslatedDeclarationEntry`.
|
||||
*/
|
||||
abstract class TranslatedDeclarationEntry extends TranslatedElement, TTranslatedDeclarationEntry {
|
||||
DeclarationEntry entry;
|
||||
PseudoDeclarationEntry entry;
|
||||
|
||||
TranslatedDeclarationEntry() { this = TTranslatedDeclarationEntry(entry) }
|
||||
|
||||
final override Function getFunction() {
|
||||
exists(DeclStmt stmt |
|
||||
stmt.getADeclarationEntry() = entry and
|
||||
stmt = entry.getStmt() and
|
||||
result = stmt.getEnclosingFunction()
|
||||
)
|
||||
}
|
||||
|
||||
PseudoDeclarationEntry getPseudoDeclarationEntry() { result = entry }
|
||||
|
||||
final override string toString() { result = entry.toString() }
|
||||
|
||||
final override Locatable getAst() { result = entry }
|
||||
final override Locatable getAst() { result = entry.getAst() }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = getAst() }
|
||||
@@ -216,7 +218,7 @@ class TranslatedStaticLocalVariableDeclarationEntry extends TranslatedDeclaratio
|
||||
*/
|
||||
class TranslatedStaticLocalVariableInitialization extends TranslatedElement,
|
||||
TranslatedLocalVariableDeclaration, TTranslatedStaticLocalVariableInitialization {
|
||||
VariableDeclarationEntry entry;
|
||||
PseudoVariableDeclarationEntry entry;
|
||||
StaticLocalVariable var;
|
||||
|
||||
TranslatedStaticLocalVariableInitialization() {
|
||||
@@ -226,7 +228,7 @@ class TranslatedStaticLocalVariableInitialization extends TranslatedElement,
|
||||
|
||||
final override string toString() { result = "init: " + entry.toString() }
|
||||
|
||||
final override Locatable getAst() { result = entry }
|
||||
final override Locatable getAst() { result = entry.getAst() }
|
||||
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = getAst() }
|
||||
|
||||
@@ -443,10 +443,10 @@ predicate hasTranslatedSyntheticTemporaryObject(Expr expr) {
|
||||
* necessary for automatic local variables, or for static local variables with dynamic
|
||||
* initialization.
|
||||
*/
|
||||
private predicate translateDeclarationEntry(DeclarationEntry entry) {
|
||||
private predicate translateDeclarationEntry(PseudoDeclarationEntry entry) {
|
||||
exists(DeclStmt declStmt, LocalVariable var |
|
||||
translateStmt(declStmt) and
|
||||
declStmt.getADeclarationEntry() = entry and
|
||||
declStmt = entry.getStmt() and
|
||||
// Only declarations of local variables need to be translated to IR.
|
||||
var = entry.getDeclaration() and
|
||||
(
|
||||
@@ -458,6 +458,100 @@ private predicate translateDeclarationEntry(DeclarationEntry entry) {
|
||||
)
|
||||
}
|
||||
|
||||
private module PseudoDeclarationEntries {
|
||||
private newtype TPseudoDeclarationEntry =
|
||||
TPresentDeclarationEntry(DeclarationEntry entry) or
|
||||
TMissingDeclarationEntry(DeclStmt stmt, Declaration d, int index) {
|
||||
not exists(stmt.getDeclarationEntry(index)) and
|
||||
stmt.getDeclaration(index) = d
|
||||
}
|
||||
|
||||
/**
|
||||
* An entity that represents a declaration entry in the database.
|
||||
*
|
||||
* This class exists to work around the fact that `DeclStmt`s in
|
||||
* template instantiations do not have `DeclarationEntry`s.
|
||||
*
|
||||
* So instead, the IR works with `PseudoDeclarationEntry`s that synthesize
|
||||
* missing `DeclarationEntry`s when there is no result for `DeclStmt::getDeclarationEntry`.
|
||||
*/
|
||||
abstract class PseudoDeclarationEntry extends TPseudoDeclarationEntry {
|
||||
/** Gets a string representation of this `PseudoDeclarationEntry`. */
|
||||
abstract string toString();
|
||||
|
||||
/** Gets the `DeclStmt` that this `PseudoDeclarationEntry` belongs to. */
|
||||
abstract DeclStmt getStmt();
|
||||
|
||||
/** Gets the `Declaration` declared by this `PseudoDeclarationEntry`. */
|
||||
abstract Declaration getDeclaration();
|
||||
|
||||
/** Gets the AST represented by this `PseudoDeclarationEntry`. */
|
||||
abstract Locatable getAst();
|
||||
|
||||
/**
|
||||
* Holds if this `PseudoDeclarationEntry` is the `index`'th entry
|
||||
* declared by the enclosing `DeclStmt`.
|
||||
*/
|
||||
abstract predicate hasIndex(int index);
|
||||
}
|
||||
|
||||
/** A `PseudoDeclarationEntry` for an existing `DeclarationEntry`. */
|
||||
private class PresentDeclarationEntry extends PseudoDeclarationEntry, TPresentDeclarationEntry {
|
||||
DeclarationEntry entry;
|
||||
|
||||
PresentDeclarationEntry() { this = TPresentDeclarationEntry(entry) }
|
||||
|
||||
override string toString() { result = entry.toString() }
|
||||
|
||||
override DeclStmt getStmt() { result.getADeclarationEntry() = entry }
|
||||
|
||||
override Declaration getDeclaration() { result = entry.getDeclaration() }
|
||||
|
||||
override Locatable getAst() { result = entry }
|
||||
|
||||
override predicate hasIndex(int index) { this.getStmt().getDeclarationEntry(index) = entry }
|
||||
}
|
||||
|
||||
/**
|
||||
* A synthesized `DeclarationEntry` that is created when a `DeclStmt` is missing a
|
||||
* result for `DeclStmt::getDeclarationEntry`
|
||||
*/
|
||||
private class MissingDeclarationEntry extends PseudoDeclarationEntry, TMissingDeclarationEntry {
|
||||
DeclStmt stmt;
|
||||
Declaration d;
|
||||
int index;
|
||||
|
||||
MissingDeclarationEntry() { this = TMissingDeclarationEntry(stmt, d, index) }
|
||||
|
||||
override string toString() { result = "pseudo declaration of " + d.getName() }
|
||||
|
||||
override DeclStmt getStmt() { result = stmt }
|
||||
|
||||
override Declaration getDeclaration() { result = d }
|
||||
|
||||
override Locatable getAst() { result = stmt }
|
||||
|
||||
override predicate hasIndex(int idx) { idx = index }
|
||||
}
|
||||
|
||||
/** A `PseudoDeclarationEntry` that represents an entry for a `Variable`. */
|
||||
class PseudoVariableDeclarationEntry instanceof PseudoDeclarationEntry {
|
||||
Variable v;
|
||||
|
||||
PseudoVariableDeclarationEntry() { super.getDeclaration() = v }
|
||||
|
||||
Variable getDeclaration() { result = v }
|
||||
|
||||
string toString() { result = super.toString() }
|
||||
|
||||
Locatable getAst() { result = super.getAst() }
|
||||
|
||||
DeclStmt getStmt() { result = super.getStmt() }
|
||||
}
|
||||
}
|
||||
|
||||
import PseudoDeclarationEntries
|
||||
|
||||
newtype TTranslatedElement =
|
||||
// An expression that is not being consumed as a condition
|
||||
TTranslatedValueExpr(Expr expr) {
|
||||
@@ -613,10 +707,10 @@ newtype TTranslatedElement =
|
||||
)
|
||||
} or
|
||||
// A local declaration
|
||||
TTranslatedDeclarationEntry(DeclarationEntry entry) { translateDeclarationEntry(entry) } or
|
||||
TTranslatedDeclarationEntry(PseudoDeclarationEntry entry) { translateDeclarationEntry(entry) } or
|
||||
// The dynamic initialization of a static local variable. This is a separate object from the
|
||||
// declaration entry.
|
||||
TTranslatedStaticLocalVariableInitialization(DeclarationEntry entry) {
|
||||
TTranslatedStaticLocalVariableInitialization(PseudoDeclarationEntry entry) {
|
||||
translateDeclarationEntry(entry) and
|
||||
entry.getDeclaration() instanceof StaticLocalVariable
|
||||
} or
|
||||
|
||||
@@ -3,8 +3,6 @@ unexpectedOperand
|
||||
duplicateOperand
|
||||
missingPhiOperand
|
||||
missingOperandType
|
||||
| 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() |
|
||||
| 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() |
|
||||
duplicateChiOperand
|
||||
sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
|
||||
@@ -3,8 +3,6 @@ unexpectedOperand
|
||||
duplicateOperand
|
||||
missingPhiOperand
|
||||
missingOperandType
|
||||
| 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() |
|
||||
| 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() |
|
||||
duplicateChiOperand
|
||||
sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
|
||||
@@ -5303,10 +5303,10 @@
|
||||
| ir.cpp:1077:39:1077:39 | Address | &:r1077_7 |
|
||||
| ir.cpp:1077:39:1077:39 | Load | m1077_6 |
|
||||
| ir.cpp:1077:39:1077:39 | SideEffect | m1077_8 |
|
||||
| ir.cpp:1078:5:1078:5 | Address | &:r1078_1 |
|
||||
| ir.cpp:1078:5:1078:5 | Address | &:r1078_7 |
|
||||
| ir.cpp:1078:5:1078:5 | Address | &:r1078_15 |
|
||||
| ir.cpp:1078:14:1078:14 | Address | &:r1078_33 |
|
||||
| ir.cpp:1078:5:1082:5 | Address | &:r1078_1 |
|
||||
| ir.cpp:1078:5:1082:5 | Address | &:r1078_7 |
|
||||
| ir.cpp:1078:5:1082:5 | Address | &:r1078_15 |
|
||||
| ir.cpp:1078:5:1082:5 | Address | &:r1078_33 |
|
||||
| ir.cpp:1078:18:1078:18 | Address | &:r1078_2 |
|
||||
| ir.cpp:1078:18:1078:18 | Address | &:r1078_8 |
|
||||
| ir.cpp:1078:18:1078:18 | Address | &:r1078_16 |
|
||||
@@ -5369,10 +5369,10 @@
|
||||
| ir.cpp:1079:13:1079:13 | Load | m1078_40 |
|
||||
| ir.cpp:1079:13:1079:17 | Condition | r1079_4 |
|
||||
| ir.cpp:1079:17:1079:17 | Right | r1079_3 |
|
||||
| ir.cpp:1084:5:1084:5 | Address | &:r1084_1 |
|
||||
| ir.cpp:1084:5:1084:5 | Address | &:r1084_7 |
|
||||
| ir.cpp:1084:5:1084:5 | Address | &:r1084_15 |
|
||||
| ir.cpp:1084:21:1084:21 | Address | &:r1084_42 |
|
||||
| ir.cpp:1084:5:1088:5 | Address | &:r1084_1 |
|
||||
| ir.cpp:1084:5:1088:5 | Address | &:r1084_7 |
|
||||
| ir.cpp:1084:5:1088:5 | Address | &:r1084_15 |
|
||||
| ir.cpp:1084:5:1088:5 | Address | &:r1084_42 |
|
||||
| ir.cpp:1084:25:1084:25 | Address | &:r1084_2 |
|
||||
| ir.cpp:1084:25:1084:25 | Address | &:r1084_8 |
|
||||
| ir.cpp:1084:25:1084:25 | Address | &:r1084_16 |
|
||||
@@ -8703,15 +8703,17 @@
|
||||
| ir.cpp:1875:13:1875:13 | Load | m1879_9 |
|
||||
| ir.cpp:1875:13:1875:13 | SideEffect | m1875_3 |
|
||||
| ir.cpp:1875:13:1875:13 | SideEffect | m1875_8 |
|
||||
| ir.cpp:1876:13:1876:29 | Address | &:r1876_1 |
|
||||
| ir.cpp:1876:13:1876:29 | Address | &:r1876_3 |
|
||||
| ir.cpp:1877:13:1877:14 | Address | &:r1877_4 |
|
||||
| ir.cpp:1877:13:1877:19 | ChiPartial | partial:m1877_5 |
|
||||
| ir.cpp:1877:13:1877:19 | ChiTotal | total:~m? |
|
||||
| ir.cpp:1877:13:1877:19 | ChiTotal | total:m1876_2 |
|
||||
| ir.cpp:1877:14:1877:14 | Unary | r1877_2 |
|
||||
| ir.cpp:1877:14:1877:14 | Unary | r1877_3 |
|
||||
| ir.cpp:1877:18:1877:19 | StoreValue | r1877_1 |
|
||||
| ir.cpp:1878:13:1878:14 | Address | &:r1878_4 |
|
||||
| ir.cpp:1878:13:1878:19 | ChiPartial | partial:m1878_5 |
|
||||
| ir.cpp:1878:13:1878:19 | ChiTotal | total:~m? |
|
||||
| ir.cpp:1878:13:1878:19 | ChiTotal | total:m1876_4 |
|
||||
| ir.cpp:1878:14:1878:14 | Unary | r1878_2 |
|
||||
| ir.cpp:1878:14:1878:14 | Unary | r1878_3 |
|
||||
| ir.cpp:1878:18:1878:19 | StoreValue | r1878_1 |
|
||||
|
||||
@@ -6,7 +6,6 @@ missingOperandType
|
||||
duplicateChiOperand
|
||||
sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
| ../../../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() |
|
||||
ambiguousSuccessors
|
||||
unexplainedLoop
|
||||
unnecessaryPhiInstruction
|
||||
|
||||
@@ -9987,6 +9987,10 @@ ir.cpp:
|
||||
# 1875| mu1875_5(glval<Bar2<int>>) = InitializeParameter[#this] : &:r1875_4
|
||||
# 1875| r1875_6(glval<Bar2<int>>) = Load[#this] : &:r1875_4, ~m?
|
||||
# 1875| mu1875_7(Bar2<int>) = InitializeIndirection[#this] : &:r1875_6
|
||||
# 1876| r1876_1(glval<int[10]>) = VariableAddress[x] :
|
||||
# 1876| mu1876_2(int[10]) = Uninitialized[x] : &:r1876_1
|
||||
# 1876| r1876_3(glval<int[10]>) = VariableAddress[y] :
|
||||
# 1876| mu1876_4(int[10]) = Uninitialized[y] : &:r1876_3
|
||||
# 1877| r1877_1(int) = Constant[10] :
|
||||
# 1877| r1877_2(glval<int[10]>) = VariableAddress[x] :
|
||||
# 1877| r1877_3(int *) = Convert : r1877_2
|
||||
|
||||
Reference in New Issue
Block a user