mirror of
https://github.com/github/codeql.git
synced 2025-12-23 04:06:37 +01:00
C++: IR translation for non-runtime-initialized static local variables.
This commit is contained in:
@@ -6,7 +6,7 @@ private import IRFunctionBaseInternal
|
|||||||
|
|
||||||
private newtype TIRFunction =
|
private newtype TIRFunction =
|
||||||
TFunctionIRFunction(Language::Function func) { IRConstruction::Raw::functionHasIR(func) } or
|
TFunctionIRFunction(Language::Function func) { IRConstruction::Raw::functionHasIR(func) } or
|
||||||
TVarInitIRFunction(Language::GlobalVariable var) { IRConstruction::Raw::varHasIRFunc(var) }
|
TVarInitIRFunction(Language::Variable var) { IRConstruction::Raw::varHasIRFunc(var) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The IR for a function. This base class contains only the predicates that are the same between all
|
* The IR for a function. This base class contains only the predicates that are the same between all
|
||||||
|
|||||||
@@ -37,7 +37,13 @@ module Raw {
|
|||||||
predicate functionHasIR(Function func) { exists(getTranslatedFunction(func)) }
|
predicate functionHasIR(Function func) { exists(getTranslatedFunction(func)) }
|
||||||
|
|
||||||
cached
|
cached
|
||||||
predicate varHasIRFunc(GlobalOrNamespaceVariable var) {
|
predicate varHasIRFunc(Variable var) {
|
||||||
|
(
|
||||||
|
var instanceof GlobalOrNamespaceVariable
|
||||||
|
or
|
||||||
|
not var.isFromUninstantiatedTemplate(_) and
|
||||||
|
var instanceof StaticInitializedStaticLocalVariable
|
||||||
|
) and
|
||||||
var.hasInitializer() and
|
var.hasInitializer() and
|
||||||
(
|
(
|
||||||
not var.getType().isDeeplyConst()
|
not var.getType().isDeeplyConst()
|
||||||
@@ -75,9 +81,10 @@ module Raw {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cached
|
cached
|
||||||
predicate hasDynamicInitializationFlag(Function func, StaticLocalVariable var, CppType type) {
|
predicate hasDynamicInitializationFlag(
|
||||||
|
Function func, RuntimeInitializedStaticLocalVariable var, CppType type
|
||||||
|
) {
|
||||||
var.getFunction() = func and
|
var.getFunction() = func and
|
||||||
var.hasDynamicInitialization() and
|
|
||||||
type = getBoolType()
|
type = getBoolType()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,15 +62,6 @@ private predicate ignoreExprAndDescendants(Expr expr) {
|
|||||||
// constant value.
|
// constant value.
|
||||||
isIRConstant(getRealParent(expr))
|
isIRConstant(getRealParent(expr))
|
||||||
or
|
or
|
||||||
// Only translate the initializer of a static local if it uses run-time data.
|
|
||||||
// Otherwise the initializer does not run in function scope.
|
|
||||||
exists(Initializer init, StaticStorageDurationVariable var |
|
|
||||||
init = var.getInitializer() and
|
|
||||||
not var.hasDynamicInitialization() and
|
|
||||||
expr = init.getExpr().getFullyConverted() and
|
|
||||||
not var instanceof GlobalOrNamespaceVariable
|
|
||||||
)
|
|
||||||
or
|
|
||||||
// Ignore descendants of `__assume` expressions, since we translated these to `NoOp`.
|
// Ignore descendants of `__assume` expressions, since we translated these to `NoOp`.
|
||||||
getRealParent(expr) instanceof AssumeExpr
|
getRealParent(expr) instanceof AssumeExpr
|
||||||
or
|
or
|
||||||
@@ -438,6 +429,17 @@ predicate hasTranslatedSyntheticTemporaryObject(Expr expr) {
|
|||||||
not expr.hasLValueToRValueConversion()
|
not expr.hasLValueToRValueConversion()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class StaticInitializedStaticLocalVariable extends StaticLocalVariable {
|
||||||
|
StaticInitializedStaticLocalVariable() {
|
||||||
|
this.hasInitializer() and
|
||||||
|
not this.hasDynamicInitialization()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RuntimeInitializedStaticLocalVariable extends StaticLocalVariable {
|
||||||
|
RuntimeInitializedStaticLocalVariable() { this.hasDynamicInitialization() }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if the specified `DeclarationEntry` needs an IR translation. An IR translation is only
|
* Holds if the specified `DeclarationEntry` needs an IR translation. An IR translation is only
|
||||||
* necessary for automatic local variables, or for static local variables with dynamic
|
* necessary for automatic local variables, or for static local variables with dynamic
|
||||||
@@ -453,7 +455,7 @@ private predicate translateDeclarationEntry(IRDeclarationEntry entry) {
|
|||||||
not var.isStatic()
|
not var.isStatic()
|
||||||
or
|
or
|
||||||
// Ignore static variables unless they have a dynamic initializer.
|
// Ignore static variables unless they have a dynamic initializer.
|
||||||
var.(StaticLocalVariable).hasDynamicInitialization()
|
var instanceof RuntimeInitializedStaticLocalVariable
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -755,7 +757,7 @@ newtype TTranslatedElement =
|
|||||||
} or
|
} or
|
||||||
// The side effect that initializes newly-allocated memory.
|
// The side effect that initializes newly-allocated memory.
|
||||||
TTranslatedAllocationSideEffect(AllocationExpr expr) { not ignoreSideEffects(expr) } or
|
TTranslatedAllocationSideEffect(AllocationExpr expr) { not ignoreSideEffects(expr) } or
|
||||||
TTranslatedGlobalOrNamespaceVarInit(GlobalOrNamespaceVariable var) { Raw::varHasIRFunc(var) }
|
TTranslatedStaticStorageDurationVarInit(Variable var) { Raw::varHasIRFunc(var) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the index of the first explicitly initialized element in `initList`
|
* Gets the index of the first explicitly initialized element in `initList`
|
||||||
@@ -1043,6 +1045,6 @@ abstract class TranslatedRootElement extends TranslatedElement {
|
|||||||
TranslatedRootElement() {
|
TranslatedRootElement() {
|
||||||
this instanceof TTranslatedFunction
|
this instanceof TTranslatedFunction
|
||||||
or
|
or
|
||||||
this instanceof TTranslatedGlobalOrNamespaceVarInit
|
this instanceof TTranslatedStaticStorageDurationVarInit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -322,6 +322,8 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
|
|||||||
(
|
(
|
||||||
var instanceof GlobalOrNamespaceVariable
|
var instanceof GlobalOrNamespaceVariable
|
||||||
or
|
or
|
||||||
|
var instanceof StaticLocalVariable
|
||||||
|
or
|
||||||
var instanceof MemberVariable and not var instanceof Field
|
var instanceof MemberVariable and not var instanceof Field
|
||||||
) and
|
) and
|
||||||
exists(VariableAccess access |
|
exists(VariableAccess access |
|
||||||
|
|||||||
@@ -8,16 +8,16 @@ private import TranslatedInitialization
|
|||||||
private import InstructionTag
|
private import InstructionTag
|
||||||
private import semmle.code.cpp.ir.internal.IRUtilities
|
private import semmle.code.cpp.ir.internal.IRUtilities
|
||||||
|
|
||||||
class TranslatedGlobalOrNamespaceVarInit extends TranslatedRootElement,
|
class TranslatedStaticStorageDurationVarInit extends TranslatedRootElement,
|
||||||
TTranslatedGlobalOrNamespaceVarInit, InitializationContext
|
TTranslatedStaticStorageDurationVarInit, InitializationContext
|
||||||
{
|
{
|
||||||
GlobalOrNamespaceVariable var;
|
Variable var;
|
||||||
|
|
||||||
TranslatedGlobalOrNamespaceVarInit() { this = TTranslatedGlobalOrNamespaceVarInit(var) }
|
TranslatedStaticStorageDurationVarInit() { this = TTranslatedStaticStorageDurationVarInit(var) }
|
||||||
|
|
||||||
override string toString() { result = var.toString() }
|
override string toString() { result = var.toString() }
|
||||||
|
|
||||||
final override GlobalOrNamespaceVariable getAst() { result = var }
|
final override Variable getAst() { result = var }
|
||||||
|
|
||||||
final override Declaration getFunction() { result = var }
|
final override Declaration getFunction() { result = var }
|
||||||
|
|
||||||
@@ -111,6 +111,8 @@ class TranslatedGlobalOrNamespaceVarInit extends TranslatedRootElement,
|
|||||||
(
|
(
|
||||||
varUsed instanceof GlobalOrNamespaceVariable
|
varUsed instanceof GlobalOrNamespaceVariable
|
||||||
or
|
or
|
||||||
|
varUsed instanceof StaticLocalVariable
|
||||||
|
or
|
||||||
varUsed instanceof MemberVariable and not varUsed instanceof Field
|
varUsed instanceof MemberVariable and not varUsed instanceof Field
|
||||||
) and
|
) and
|
||||||
exists(VariableAccess access |
|
exists(VariableAccess access |
|
||||||
@@ -128,6 +130,4 @@ class TranslatedGlobalOrNamespaceVarInit extends TranslatedRootElement,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TranslatedGlobalOrNamespaceVarInit getTranslatedVarInit(GlobalOrNamespaceVariable var) {
|
TranslatedStaticStorageDurationVarInit getTranslatedVarInit(Variable var) { result.getAst() = var }
|
||||||
result.getAst() = var
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -139,7 +139,8 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn
|
|||||||
|
|
||||||
final override Declaration getFunction() {
|
final override Declaration getFunction() {
|
||||||
result = expr.getEnclosingFunction() or
|
result = expr.getEnclosingFunction() or
|
||||||
result = expr.getEnclosingVariable().(GlobalOrNamespaceVariable)
|
result = expr.getEnclosingVariable().(GlobalOrNamespaceVariable) or
|
||||||
|
result = expr.getEnclosingVariable().(StaticInitializedStaticLocalVariable)
|
||||||
}
|
}
|
||||||
|
|
||||||
final override Locatable getAst() { result = expr }
|
final override Locatable getAst() { result = expr }
|
||||||
@@ -654,6 +655,8 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
|
|||||||
result = initList.getEnclosingFunction()
|
result = initList.getEnclosingFunction()
|
||||||
or
|
or
|
||||||
result = initList.getEnclosingVariable().(GlobalOrNamespaceVariable)
|
result = initList.getEnclosingVariable().(GlobalOrNamespaceVariable)
|
||||||
|
or
|
||||||
|
result = initList.getEnclosingVariable().(StaticInitializedStaticLocalVariable)
|
||||||
}
|
}
|
||||||
|
|
||||||
final override Instruction getFirstInstruction() { result = getInstruction(getElementIndexTag()) }
|
final override Instruction getFirstInstruction() { result = getInstruction(getElementIndexTag()) }
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class Variable = Cpp::Variable;
|
|||||||
|
|
||||||
class AutomaticVariable = Cpp::StackVariable;
|
class AutomaticVariable = Cpp::StackVariable;
|
||||||
|
|
||||||
class StaticVariable = Cpp::Variable;
|
class StaticVariable = Cpp::StaticStorageDurationVariable;
|
||||||
|
|
||||||
class GlobalVariable = Cpp::GlobalOrNamespaceVariable;
|
class GlobalVariable = Cpp::GlobalOrNamespaceVariable;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
private import cpp
|
||||||
private import semmle.code.cpp.Print as Print
|
private import semmle.code.cpp.Print as Print
|
||||||
|
|
||||||
predicate getIdentityString = Print::getIdentityString/1;
|
string getIdentityString(Declaration decl) {
|
||||||
|
if decl instanceof StaticLocalVariable
|
||||||
|
then
|
||||||
|
exists(StaticLocalVariable v | v = decl | result = v.getType().toString() + " " + v.getName())
|
||||||
|
else result = Print::getIdentityString(decl)
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,5 +18,7 @@ predicate shouldDumpFunction(Declaration decl) {
|
|||||||
decl instanceof Function
|
decl instanceof Function
|
||||||
or
|
or
|
||||||
decl.(GlobalOrNamespaceVariable).hasInitializer()
|
decl.(GlobalOrNamespaceVariable).hasInitializer()
|
||||||
|
or
|
||||||
|
decl.(StaticLocalVariable).hasInitializer()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ private import IRFunctionBaseInternal
|
|||||||
|
|
||||||
private newtype TIRFunction =
|
private newtype TIRFunction =
|
||||||
TFunctionIRFunction(Language::Function func) { IRConstruction::Raw::functionHasIR(func) } or
|
TFunctionIRFunction(Language::Function func) { IRConstruction::Raw::functionHasIR(func) } or
|
||||||
TVarInitIRFunction(Language::GlobalVariable var) { IRConstruction::Raw::varHasIRFunc(var) }
|
TVarInitIRFunction(Language::Variable var) { IRConstruction::Raw::varHasIRFunc(var) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The IR for a function. This base class contains only the predicates that are the same between all
|
* The IR for a function. This base class contains only the predicates that are the same between all
|
||||||
|
|||||||
Reference in New Issue
Block a user