Skip to content

Commit 5f4d089

Browse files
authored
Merge pull request github#12900 from MathiasVP/ir-translate-constant-static-local-vars-2
2 parents 6c095d8 + 6bfdbef commit 5f4d089

File tree

19 files changed

+359
-52
lines changed

19 files changed

+359
-52
lines changed

cpp/ql/lib/semmle/code/cpp/ir/implementation/internal/IRFunctionBase.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ private import IRFunctionBaseInternal
66

77
private newtype TIRFunction =
88
TFunctionIRFunction(Language::Function func) { IRConstruction::Raw::functionHasIR(func) } or
9-
TVarInitIRFunction(Language::GlobalVariable var) { IRConstruction::Raw::varHasIRFunc(var) }
9+
TVarInitIRFunction(Language::Variable var) { IRConstruction::Raw::varHasIRFunc(var) }
1010

1111
/**
1212
* The IR for a function. This base class contains only the predicates that are the same between all

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,13 @@ module Raw {
3737
predicate functionHasIR(Function func) { exists(getTranslatedFunction(func)) }
3838

3939
cached
40-
predicate varHasIRFunc(GlobalOrNamespaceVariable var) {
40+
predicate varHasIRFunc(Variable var) {
41+
(
42+
var instanceof GlobalOrNamespaceVariable
43+
or
44+
not var.isFromUninstantiatedTemplate(_) and
45+
var instanceof StaticInitializedStaticLocalVariable
46+
) and
4147
var.hasInitializer() and
4248
(
4349
not var.getType().isDeeplyConst()
@@ -75,9 +81,10 @@ module Raw {
7581
}
7682

7783
cached
78-
predicate hasDynamicInitializationFlag(Function func, StaticLocalVariable var, CppType type) {
84+
predicate hasDynamicInitializationFlag(
85+
Function func, RuntimeInitializedStaticLocalVariable var, CppType type
86+
) {
7987
var.getFunction() = func and
80-
var.hasDynamicInitialization() and
8188
type = getBoolType()
8289
}
8390

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ abstract class TranslatedSideEffects extends TranslatedElement {
180180
/** DEPRECATED: Alias for getAst */
181181
deprecated override Locatable getAST() { result = getAst() }
182182

183-
final override Declaration getFunction() { result = getExpr().getEnclosingDeclaration() }
183+
final override Declaration getFunction() { result = getEnclosingDeclaration(getExpr()) }
184184

185185
final override TranslatedElement getChild(int i) {
186186
result =

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ abstract class TranslatedCondition extends TranslatedElement {
2828

2929
final Expr getExpr() { result = expr }
3030

31-
final override Function getFunction() { result = expr.getEnclosingFunction() }
31+
final override Declaration getFunction() {
32+
result = getEnclosingFunction(expr) or
33+
result = getEnclosingVariable(expr).(GlobalOrNamespaceVariable) or
34+
result = getEnclosingVariable(expr).(StaticInitializedStaticLocalVariable)
35+
}
3236

3337
final Type getResultType() { result = expr.getUnspecifiedType() }
3438
}

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,14 @@ abstract class TranslatedDeclarationEntry extends TranslatedElement, TTranslated
2828

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

31-
final override Function getFunction() {
32-
exists(DeclStmt stmt |
33-
stmt = entry.getStmt() and
31+
final override Declaration getFunction() {
32+
exists(DeclStmt stmt | stmt = entry.getStmt() |
33+
result = entry.getDeclaration().(StaticInitializedStaticLocalVariable)
34+
or
35+
result = entry.getDeclaration().(GlobalOrNamespaceVariable)
36+
or
37+
not entry.getDeclaration() instanceof StaticInitializedStaticLocalVariable and
38+
not entry.getDeclaration() instanceof GlobalOrNamespaceVariable and
3439
result = stmt.getEnclosingFunction()
3540
)
3641
}
@@ -237,7 +242,7 @@ class TranslatedStaticLocalVariableInitialization extends TranslatedElement,
237242

238243
final override LocalVariable getVariable() { result = var }
239244

240-
final override Function getFunction() { result = var.getFunction() }
245+
final override Declaration getFunction() { result = var.getFunction() }
241246
}
242247

243248
TranslatedConditionDecl getTranslatedConditionDecl(ConditionDeclExpr expr) {
@@ -264,7 +269,7 @@ class TranslatedConditionDecl extends TranslatedLocalVariableDeclaration, TTrans
264269
/** DEPRECATED: Alias for getAst */
265270
deprecated override Locatable getAST() { result = getAst() }
266271

267-
override Function getFunction() { result = conditionDeclExpr.getEnclosingFunction() }
272+
override Declaration getFunction() { result = getEnclosingFunction(conditionDeclExpr) }
268273

269274
override LocalVariable getVariable() { result = conditionDeclExpr.getVariable() }
270275
}

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

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,6 @@ private predicate ignoreExprAndDescendants(Expr expr) {
6262
// constant value.
6363
isIRConstant(getRealParent(expr))
6464
or
65-
// Only translate the initializer of a static local if it uses run-time data.
66-
// Otherwise the initializer does not run in function scope.
67-
exists(Initializer init, StaticStorageDurationVariable var |
68-
init = var.getInitializer() and
69-
not var.hasDynamicInitialization() and
70-
expr = init.getExpr().getFullyConverted() and
71-
not var instanceof GlobalOrNamespaceVariable
72-
)
73-
or
7465
// Ignore descendants of `__assume` expressions, since we translated these to `NoOp`.
7566
getRealParent(expr) instanceof AssumeExpr
7667
or
@@ -118,8 +109,8 @@ private predicate ignoreExprOnly(Expr expr) {
118109
// should not be translated.
119110
exists(NewOrNewArrayExpr new | expr = new.getAllocatorCall().getArgument(0))
120111
or
121-
not translateFunction(expr.getEnclosingFunction()) and
122-
not Raw::varHasIRFunc(expr.getEnclosingVariable())
112+
not translateFunction(getEnclosingFunction(expr)) and
113+
not Raw::varHasIRFunc(getEnclosingVariable(expr))
123114
or
124115
// We do not yet translate destructors properly, so for now we ignore the
125116
// destructor call. We do, however, translate the expression being
@@ -438,6 +429,17 @@ predicate hasTranslatedSyntheticTemporaryObject(Expr expr) {
438429
not expr.hasLValueToRValueConversion()
439430
}
440431

432+
class StaticInitializedStaticLocalVariable extends StaticLocalVariable {
433+
StaticInitializedStaticLocalVariable() {
434+
this.hasInitializer() and
435+
not this.hasDynamicInitialization()
436+
}
437+
}
438+
439+
class RuntimeInitializedStaticLocalVariable extends StaticLocalVariable {
440+
RuntimeInitializedStaticLocalVariable() { this.hasDynamicInitialization() }
441+
}
442+
441443
/**
442444
* Holds if the specified `DeclarationEntry` needs an IR translation. An IR translation is only
443445
* necessary for automatic local variables, or for static local variables with dynamic
@@ -453,7 +455,7 @@ private predicate translateDeclarationEntry(IRDeclarationEntry entry) {
453455
not var.isStatic()
454456
or
455457
// Ignore static variables unless they have a dynamic initializer.
456-
var.(StaticLocalVariable).hasDynamicInitialization()
458+
var instanceof RuntimeInitializedStaticLocalVariable
457459
)
458460
)
459461
}
@@ -755,7 +757,7 @@ newtype TTranslatedElement =
755757
} or
756758
// The side effect that initializes newly-allocated memory.
757759
TTranslatedAllocationSideEffect(AllocationExpr expr) { not ignoreSideEffects(expr) } or
758-
TTranslatedGlobalOrNamespaceVarInit(GlobalOrNamespaceVariable var) { Raw::varHasIRFunc(var) }
760+
TTranslatedStaticStorageDurationVarInit(Variable var) { Raw::varHasIRFunc(var) }
759761

760762
/**
761763
* Gets the index of the first explicitly initialized element in `initList`
@@ -1043,6 +1045,6 @@ abstract class TranslatedRootElement extends TranslatedElement {
10431045
TranslatedRootElement() {
10441046
this instanceof TTranslatedFunction
10451047
or
1046-
this instanceof TTranslatedGlobalOrNamespaceVarInit
1048+
this instanceof TTranslatedStaticStorageDurationVarInit
10471049
}
10481050
}

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

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ abstract class TranslatedExpr extends TranslatedElement {
7979
/** DEPRECATED: Alias for getAst */
8080
deprecated override Locatable getAST() { result = this.getAst() }
8181

82-
final override Declaration getFunction() { result = expr.getEnclosingDeclaration() }
82+
final override Declaration getFunction() { result = getEnclosingDeclaration(expr) }
8383

8484
/**
8585
* Gets the expression from which this `TranslatedExpr` is generated.
@@ -90,12 +90,57 @@ abstract class TranslatedExpr extends TranslatedElement {
9090
* Gets the `TranslatedFunction` containing this expression.
9191
*/
9292
final TranslatedRootElement getEnclosingFunction() {
93-
result = getTranslatedFunction(expr.getEnclosingFunction())
93+
result = getTranslatedFunction(getEnclosingFunction(expr))
9494
or
95-
result = getTranslatedVarInit(expr.getEnclosingVariable())
95+
result = getTranslatedVarInit(getEnclosingVariable(expr))
9696
}
9797
}
9898

99+
Function getEnclosingFunction(Expr e) {
100+
not exists(getEnclosingVariable(e)) and
101+
result = e.getEnclosingFunction()
102+
}
103+
104+
Declaration getEnclosingDeclaration0(Expr e) {
105+
result = getEnclosingDeclaration0(e.getParentWithConversions())
106+
or
107+
exists(Initializer i, Variable v |
108+
i.getExpr().getFullyConverted() = e and
109+
v = i.getDeclaration()
110+
|
111+
if v instanceof StaticInitializedStaticLocalVariable or v instanceof GlobalOrNamespaceVariable
112+
then result = v
113+
else result = e.getEnclosingDeclaration()
114+
)
115+
}
116+
117+
Declaration getEnclosingDeclaration(Expr e) {
118+
result = getEnclosingDeclaration0(e)
119+
or
120+
not exists(getEnclosingDeclaration0(e)) and
121+
result = e.getEnclosingDeclaration()
122+
}
123+
124+
Variable getEnclosingVariable0(Expr e) {
125+
result = getEnclosingVariable0(e.getParentWithConversions())
126+
or
127+
exists(Initializer i, Variable v |
128+
i.getExpr().getFullyConverted() = e and
129+
v = i.getDeclaration()
130+
|
131+
if v instanceof StaticInitializedStaticLocalVariable or v instanceof GlobalOrNamespaceVariable
132+
then result = v
133+
else result = e.getEnclosingVariable()
134+
)
135+
}
136+
137+
Variable getEnclosingVariable(Expr e) {
138+
result = getEnclosingVariable0(e)
139+
or
140+
not exists(getEnclosingVariable0(e)) and
141+
result = e.getEnclosingVariable()
142+
}
143+
99144
/**
100145
* The IR translation of the "core" part of an expression. This is the part of
101146
* the expression that produces the result value of the expression, before any
@@ -843,10 +888,21 @@ class TranslatedNonFieldVariableAccess extends TranslatedVariableAccess {
843888

844889
override IRVariable getInstructionVariable(InstructionTag tag) {
845890
tag = OnlyInstructionTag() and
846-
result = getIRUserVariable(expr.getEnclosingDeclaration(), expr.getTarget())
891+
exists(Declaration d, Variable v |
892+
accessHasEnclosingDeclarationAndVariable(d, v, expr) and
893+
result = getIRUserVariable(d, v)
894+
)
847895
}
848896
}
849897

898+
pragma[nomagic]
899+
private predicate accessHasEnclosingDeclarationAndVariable(
900+
Declaration d, Variable v, VariableAccess va
901+
) {
902+
d = getEnclosingDeclaration(va) and
903+
v = va.getTarget()
904+
}
905+
850906
class TranslatedFieldAccess extends TranslatedVariableAccess {
851907
override FieldAccess expr;
852908

@@ -2000,7 +2056,7 @@ class TranslatedDestructorFieldDestruction extends TranslatedNonConstantExpr, St
20002056
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
20012057
tag = OnlyInstructionTag() and
20022058
operandTag instanceof UnaryOperandTag and
2003-
result = getTranslatedFunction(expr.getEnclosingFunction()).getInitializeThisInstruction()
2059+
result = getTranslatedFunction(getEnclosingFunction(expr)).getInitializeThisInstruction()
20042060
}
20052061

20062062
final override Field getInstructionField(InstructionTag tag) {

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,11 +322,13 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
322322
(
323323
var instanceof GlobalOrNamespaceVariable
324324
or
325+
var instanceof StaticLocalVariable
326+
or
325327
var instanceof MemberVariable and not var instanceof Field
326328
) and
327329
exists(VariableAccess access |
328330
access.getTarget() = var and
329-
access.getEnclosingFunction() = func
331+
getEnclosingFunction(access) = func
330332
)
331333
or
332334
var.(LocalScopeVariable).getFunction() = func

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

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import semmle.code.cpp.ir.implementation.raw.internal.TranslatedElement
2+
private import TranslatedExpr
23
private import cpp
34
private import semmle.code.cpp.ir.implementation.IRType
45
private import semmle.code.cpp.ir.implementation.Opcode
@@ -8,16 +9,16 @@ private import TranslatedInitialization
89
private import InstructionTag
910
private import semmle.code.cpp.ir.internal.IRUtilities
1011

11-
class TranslatedGlobalOrNamespaceVarInit extends TranslatedRootElement,
12-
TTranslatedGlobalOrNamespaceVarInit, InitializationContext
12+
class TranslatedStaticStorageDurationVarInit extends TranslatedRootElement,
13+
TTranslatedStaticStorageDurationVarInit, InitializationContext
1314
{
14-
GlobalOrNamespaceVariable var;
15+
Variable var;
1516

16-
TranslatedGlobalOrNamespaceVarInit() { this = TTranslatedGlobalOrNamespaceVarInit(var) }
17+
TranslatedStaticStorageDurationVarInit() { this = TTranslatedStaticStorageDurationVarInit(var) }
1718

1819
override string toString() { result = var.toString() }
1920

20-
final override GlobalOrNamespaceVariable getAst() { result = var }
21+
final override Variable getAst() { result = var }
2122

2223
final override Declaration getFunction() { result = var }
2324

@@ -111,11 +112,13 @@ class TranslatedGlobalOrNamespaceVarInit extends TranslatedRootElement,
111112
(
112113
varUsed instanceof GlobalOrNamespaceVariable
113114
or
115+
varUsed instanceof StaticLocalVariable
116+
or
114117
varUsed instanceof MemberVariable and not varUsed instanceof Field
115118
) and
116119
exists(VariableAccess access |
117120
access.getTarget() = varUsed and
118-
access.getEnclosingVariable() = var
121+
getEnclosingVariable(access) = var
119122
)
120123
or
121124
var = varUsed
@@ -128,6 +131,4 @@ class TranslatedGlobalOrNamespaceVarInit extends TranslatedRootElement,
128131
}
129132
}
130133

131-
TranslatedGlobalOrNamespaceVarInit getTranslatedVarInit(GlobalOrNamespaceVariable var) {
132-
result.getAst() = var
133-
}
134+
TranslatedStaticStorageDurationVarInit getTranslatedVarInit(Variable var) { result.getAst() = var }

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

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,9 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn
138138
final override string toString() { result = "init: " + expr.toString() }
139139

140140
final override Declaration getFunction() {
141-
result = expr.getEnclosingFunction() or
142-
result = expr.getEnclosingVariable().(GlobalOrNamespaceVariable)
141+
result = getEnclosingFunction(expr) or
142+
result = getEnclosingVariable(expr).(GlobalOrNamespaceVariable) or
143+
result = getEnclosingVariable(expr).(StaticInitializedStaticLocalVariable)
143144
}
144145

145146
final override Locatable getAst() { result = expr }
@@ -159,7 +160,7 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn
159160
final InitializationContext getContext() { result = getParent() }
160161

161162
final TranslatedFunction getEnclosingFunction() {
162-
result = getTranslatedFunction(expr.getEnclosingFunction())
163+
result = getTranslatedFunction(this.getFunction())
163164
}
164165
}
165166

@@ -493,8 +494,9 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
493494
deprecated override Locatable getAST() { result = getAst() }
494495

495496
final override Declaration getFunction() {
496-
result = ast.getEnclosingFunction() or
497-
result = ast.getEnclosingVariable().(GlobalOrNamespaceVariable)
497+
result = getEnclosingFunction(ast) or
498+
result = getEnclosingVariable(ast).(GlobalOrNamespaceVariable) or
499+
result = getEnclosingVariable(ast).(StaticInitializedStaticLocalVariable)
498500
}
499501

500502
final override Instruction getFirstInstruction() { result = getInstruction(getFieldAddressTag()) }
@@ -651,9 +653,11 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
651653
deprecated override Locatable getAST() { result = getAst() }
652654

653655
final override Declaration getFunction() {
654-
result = initList.getEnclosingFunction()
656+
result = getEnclosingFunction(initList)
655657
or
656-
result = initList.getEnclosingVariable().(GlobalOrNamespaceVariable)
658+
result = getEnclosingVariable(initList).(GlobalOrNamespaceVariable)
659+
or
660+
result = getEnclosingVariable(initList).(StaticInitializedStaticLocalVariable)
657661
}
658662

659663
final override Instruction getFirstInstruction() { result = getInstruction(getElementIndexTag()) }
@@ -852,7 +856,7 @@ abstract class TranslatedStructorCallFromStructor extends TranslatedElement, Str
852856
result = getStructorCall()
853857
}
854858

855-
final override Function getFunction() { result = call.getEnclosingFunction() }
859+
final override Function getFunction() { result = getEnclosingFunction(call) }
856860

857861
final override Instruction getChildSuccessor(TranslatedElement child) {
858862
child = getStructorCall() and
@@ -989,7 +993,7 @@ class TranslatedConstructorBareInit extends TranslatedElement, TTranslatedConstr
989993

990994
override TranslatedElement getChild(int id) { none() }
991995

992-
override Function getFunction() { result = getParent().getFunction() }
996+
override Declaration getFunction() { result = this.getParent().getFunction() }
993997

994998
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
995999

0 commit comments

Comments
 (0)