C++: IR translation for non-runtime-initialized static local variables.

This commit is contained in:
Mathias Vorreiter Pedersen
2023-04-18 19:19:59 +01:00
parent 4bf03e7962
commit d14ee931e1
10 changed files with 50 additions and 28 deletions

View File

@@ -6,7 +6,7 @@ private import IRFunctionBaseInternal
private newtype TIRFunction =
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

View File

@@ -37,7 +37,13 @@ module Raw {
predicate functionHasIR(Function func) { exists(getTranslatedFunction(func)) }
cached
predicate varHasIRFunc(GlobalOrNamespaceVariable var) {
predicate varHasIRFunc(Variable var) {
(
var instanceof GlobalOrNamespaceVariable
or
not var.isFromUninstantiatedTemplate(_) and
var instanceof StaticInitializedStaticLocalVariable
) and
var.hasInitializer() and
(
not var.getType().isDeeplyConst()
@@ -75,9 +81,10 @@ module Raw {
}
cached
predicate hasDynamicInitializationFlag(Function func, StaticLocalVariable var, CppType type) {
predicate hasDynamicInitializationFlag(
Function func, RuntimeInitializedStaticLocalVariable var, CppType type
) {
var.getFunction() = func and
var.hasDynamicInitialization() and
type = getBoolType()
}

View File

@@ -62,15 +62,6 @@ private predicate ignoreExprAndDescendants(Expr expr) {
// constant value.
isIRConstant(getRealParent(expr))
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`.
getRealParent(expr) instanceof AssumeExpr
or
@@ -438,6 +429,17 @@ predicate hasTranslatedSyntheticTemporaryObject(Expr expr) {
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
* necessary for automatic local variables, or for static local variables with dynamic
@@ -453,7 +455,7 @@ private predicate translateDeclarationEntry(IRDeclarationEntry entry) {
not var.isStatic()
or
// Ignore static variables unless they have a dynamic initializer.
var.(StaticLocalVariable).hasDynamicInitialization()
var instanceof RuntimeInitializedStaticLocalVariable
)
)
}
@@ -755,7 +757,7 @@ newtype TTranslatedElement =
} or
// The side effect that initializes newly-allocated memory.
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`
@@ -1043,6 +1045,6 @@ abstract class TranslatedRootElement extends TranslatedElement {
TranslatedRootElement() {
this instanceof TTranslatedFunction
or
this instanceof TTranslatedGlobalOrNamespaceVarInit
this instanceof TTranslatedStaticStorageDurationVarInit
}
}

View File

@@ -322,6 +322,8 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
(
var instanceof GlobalOrNamespaceVariable
or
var instanceof StaticLocalVariable
or
var instanceof MemberVariable and not var instanceof Field
) and
exists(VariableAccess access |

View File

@@ -8,16 +8,16 @@ private import TranslatedInitialization
private import InstructionTag
private import semmle.code.cpp.ir.internal.IRUtilities
class TranslatedGlobalOrNamespaceVarInit extends TranslatedRootElement,
TTranslatedGlobalOrNamespaceVarInit, InitializationContext
class TranslatedStaticStorageDurationVarInit extends TranslatedRootElement,
TTranslatedStaticStorageDurationVarInit, InitializationContext
{
GlobalOrNamespaceVariable var;
Variable var;
TranslatedGlobalOrNamespaceVarInit() { this = TTranslatedGlobalOrNamespaceVarInit(var) }
TranslatedStaticStorageDurationVarInit() { this = TTranslatedStaticStorageDurationVarInit(var) }
override string toString() { result = var.toString() }
final override GlobalOrNamespaceVariable getAst() { result = var }
final override Variable getAst() { result = var }
final override Declaration getFunction() { result = var }
@@ -111,6 +111,8 @@ class TranslatedGlobalOrNamespaceVarInit extends TranslatedRootElement,
(
varUsed instanceof GlobalOrNamespaceVariable
or
varUsed instanceof StaticLocalVariable
or
varUsed instanceof MemberVariable and not varUsed instanceof Field
) and
exists(VariableAccess access |
@@ -128,6 +130,4 @@ class TranslatedGlobalOrNamespaceVarInit extends TranslatedRootElement,
}
}
TranslatedGlobalOrNamespaceVarInit getTranslatedVarInit(GlobalOrNamespaceVariable var) {
result.getAst() = var
}
TranslatedStaticStorageDurationVarInit getTranslatedVarInit(Variable var) { result.getAst() = var }

View File

@@ -139,7 +139,8 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn
final override Declaration getFunction() {
result = expr.getEnclosingFunction() or
result = expr.getEnclosingVariable().(GlobalOrNamespaceVariable)
result = expr.getEnclosingVariable().(GlobalOrNamespaceVariable) or
result = expr.getEnclosingVariable().(StaticInitializedStaticLocalVariable)
}
final override Locatable getAst() { result = expr }
@@ -654,6 +655,8 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
result = initList.getEnclosingFunction()
or
result = initList.getEnclosingVariable().(GlobalOrNamespaceVariable)
or
result = initList.getEnclosingVariable().(StaticInitializedStaticLocalVariable)
}
final override Instruction getFirstInstruction() { result = getInstruction(getElementIndexTag()) }

View File

@@ -47,7 +47,7 @@ class Variable = Cpp::Variable;
class AutomaticVariable = Cpp::StackVariable;
class StaticVariable = Cpp::Variable;
class StaticVariable = Cpp::StaticStorageDurationVariable;
class GlobalVariable = Cpp::GlobalOrNamespaceVariable;

View File

@@ -1,3 +1,9 @@
private import cpp
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)
}

View File

@@ -18,5 +18,7 @@ predicate shouldDumpFunction(Declaration decl) {
decl instanceof Function
or
decl.(GlobalOrNamespaceVariable).hasInitializer()
or
decl.(StaticLocalVariable).hasInitializer()
)
}