Skip to content

Commit 424d665

Browse files
committed
C++: Generate initialization function for each NSDMI
1 parent 5cf3b8e commit 424d665

File tree

7 files changed

+288
-6
lines changed

7 files changed

+288
-6
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ private import TranslatedCall
1515
private import TranslatedStmt
1616
private import TranslatedFunction
1717
private import TranslatedGlobalVar
18+
private import TranslatedNonStaticDataMember
1819
private import TranslatedInitialization
1920

2021
TranslatedElement getInstructionTranslatedElement(Instruction instruction) {
@@ -45,6 +46,8 @@ module Raw {
4546
or
4647
not var.isFromUninstantiatedTemplate(_) and
4748
var instanceof StaticInitializedStaticLocalVariable
49+
or
50+
var instanceof Field
4851
) and
4952
var.hasInitializer() and
5053
(
@@ -64,6 +67,8 @@ module Raw {
6467
getTranslatedFunction(decl).hasUserVariable(var, type)
6568
or
6669
getTranslatedVarInit(decl).hasUserVariable(var, type)
70+
or
71+
getTranslatedFieldInit(decl).hasUserVariable(var, type)
6772
}
6873

6974
cached

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ abstract class TranslatedCondition extends TranslatedElement {
3636
final override Declaration getFunction() {
3737
result = getEnclosingFunction(expr) or
3838
result = getEnclosingVariable(expr).(GlobalOrNamespaceVariable) or
39-
result = getEnclosingVariable(expr).(StaticInitializedStaticLocalVariable)
39+
result = getEnclosingVariable(expr).(StaticInitializedStaticLocalVariable) or
40+
result = getEnclosingVariable(expr).(Field)
4041
}
4142

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

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ abstract class TranslatedDeclarationEntry extends TranslatedElement, TTranslated
3636
or
3737
not entry.getDeclaration() instanceof StaticInitializedStaticLocalVariable and
3838
not entry.getDeclaration() instanceof GlobalOrNamespaceVariable and
39+
not entry.getDeclaration() instanceof Field and
3940
result = stmt.getEnclosingFunction()
4041
)
4142
}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,10 @@ newtype TTranslatedElement =
918918
} or
919919
// The side effect that initializes newly-allocated memory.
920920
TTranslatedAllocationSideEffect(AllocationExpr expr) { not ignoreSideEffects(expr) } or
921-
TTranslatedStaticStorageDurationVarInit(Variable var) { Raw::varHasIRFunc(var) } or
921+
TTranslatedStaticStorageDurationVarInit(Variable var) {
922+
Raw::varHasIRFunc(var) and not var instanceof Field
923+
} or
924+
TTranslatedNonStaticDataMemberVarInit(Field var) { Raw::varHasIRFunc(var) } or
922925
TTranslatedAssertionOperand(MacroInvocation mi, int index) { hasAssertionOperand(mi, index) }
923926

924927
/**
@@ -1297,5 +1300,7 @@ abstract class TranslatedRootElement extends TranslatedElement {
12971300
this instanceof TTranslatedFunction
12981301
or
12991302
this instanceof TTranslatedStaticStorageDurationVarInit
1303+
or
1304+
this instanceof TTranslatedNonStaticDataMemberVarInit
13001305
}
13011306
}

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

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ private import TranslatedFunction
1414
private import TranslatedInitialization
1515
private import TranslatedStmt
1616
private import TranslatedGlobalVar
17+
private import TranslatedNonStaticDataMember
1718
private import IRConstruction
1819
import TranslatedCall
1920

@@ -138,6 +139,8 @@ abstract class TranslatedExpr extends TranslatedElement {
138139
result = getTranslatedFunction(getEnclosingFunction(expr))
139140
or
140141
result = getTranslatedVarInit(getEnclosingVariable(expr))
142+
or
143+
result = getTranslatedFieldInit(getEnclosingVariable(expr))
141144
}
142145
}
143146

@@ -153,7 +156,10 @@ Declaration getEnclosingDeclaration0(Expr e) {
153156
i.getExpr().getFullyConverted() = e and
154157
v = i.getDeclaration()
155158
|
156-
if v instanceof StaticInitializedStaticLocalVariable or v instanceof GlobalOrNamespaceVariable
159+
if
160+
v instanceof StaticInitializedStaticLocalVariable or
161+
v instanceof GlobalOrNamespaceVariable or
162+
v instanceof Field
157163
then result = v
158164
else result = e.getEnclosingDeclaration()
159165
)
@@ -173,7 +179,10 @@ Variable getEnclosingVariable0(Expr e) {
173179
i.getExpr().getFullyConverted() = e and
174180
v = i.getDeclaration()
175181
|
176-
if v instanceof StaticInitializedStaticLocalVariable or v instanceof GlobalOrNamespaceVariable
182+
if
183+
v instanceof StaticInitializedStaticLocalVariable or
184+
v instanceof GlobalOrNamespaceVariable or
185+
v instanceof Field
177186
then result = v
178187
else result = e.getEnclosingVariable()
179188
)
@@ -826,6 +835,46 @@ class TranslatedPostfixCrementOperation extends TranslatedCrementOperation {
826835
override Instruction getResult() { result = this.getLoadedOperand().getResult() }
827836
}
828837

838+
class TranslatedParamAccessForType extends TranslatedNonConstantExpr {
839+
override ParamAccessForType expr;
840+
841+
TranslatedParamAccessForType() {
842+
// Currently only needed for this parameter accesses.
843+
expr.isThisAccess()
844+
}
845+
846+
final override Instruction getFirstInstruction(EdgeKind kind) {
847+
result = this.getInstruction(OnlyInstructionTag()) and
848+
kind instanceof GotoEdge
849+
}
850+
851+
override Instruction getALastInstructionInternal() {
852+
result = this.getInstruction(OnlyInstructionTag())
853+
}
854+
855+
final override TranslatedElement getChildInternal(int id) { none() }
856+
857+
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
858+
tag = OnlyInstructionTag() and
859+
result = this.getParent().getChildSuccessor(this, kind)
860+
}
861+
862+
override Instruction getResult() { result = this.getInstruction(OnlyInstructionTag()) }
863+
864+
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
865+
tag = OnlyInstructionTag() and
866+
opcode instanceof Opcode::CopyValue and
867+
resultType = getTypeForPRValue(expr.getType())
868+
}
869+
870+
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
871+
tag = OnlyInstructionTag() and
872+
operandTag instanceof UnaryOperandTag and
873+
result =
874+
this.getEnclosingFunction().(TranslatedNonStaticDataMemberVarInit).getLoadThisInstruction()
875+
}
876+
}
877+
829878
/**
830879
* IR translation of an array access expression (e.g. `a[i]`). The array being accessed will either
831880
* be a prvalue of pointer type (possibly due to an implicit array-to-pointer conversion), or a

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn
148148
final override Declaration getFunction() {
149149
result = getEnclosingFunction(expr) or
150150
result = getEnclosingVariable(expr).(GlobalOrNamespaceVariable) or
151-
result = getEnclosingVariable(expr).(StaticInitializedStaticLocalVariable)
151+
result = getEnclosingVariable(expr).(StaticInitializedStaticLocalVariable) or
152+
result = getEnclosingVariable(expr).(Field)
152153
}
153154

154155
final override Locatable getAst() { result = expr }
@@ -528,7 +529,8 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
528529
final override Declaration getFunction() {
529530
result = getEnclosingFunction(ast) or
530531
result = getEnclosingVariable(ast).(GlobalOrNamespaceVariable) or
531-
result = getEnclosingVariable(ast).(StaticInitializedStaticLocalVariable)
532+
result = getEnclosingVariable(ast).(StaticInitializedStaticLocalVariable) or
533+
result = getEnclosingVariable(ast).(Field)
532534
}
533535

534536
final override Instruction getFirstInstruction(EdgeKind kind) {
@@ -701,6 +703,8 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
701703
result = getEnclosingVariable(initList).(GlobalOrNamespaceVariable)
702704
or
703705
result = getEnclosingVariable(initList).(StaticInitializedStaticLocalVariable)
706+
or
707+
result = getEnclosingVariable(initList).(Field)
704708
}
705709

706710
final override Instruction getFirstInstruction(EdgeKind kind) {
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
import semmle.code.cpp.ir.implementation.raw.internal.TranslatedElement
2+
private import TranslatedExpr
3+
private import cpp
4+
private import semmle.code.cpp.ir.implementation.internal.OperandTag
5+
private import semmle.code.cpp.ir.internal.TempVariableTag
6+
private import semmle.code.cpp.ir.internal.CppType
7+
private import TranslatedInitialization
8+
private import InstructionTag
9+
private import semmle.code.cpp.ir.internal.IRUtilities
10+
11+
class TranslatedNonStaticDataMemberVarInit extends TranslatedRootElement,
12+
TTranslatedNonStaticDataMemberVarInit, InitializationContext
13+
{
14+
Field field;
15+
Class cls;
16+
17+
TranslatedNonStaticDataMemberVarInit() {
18+
this = TTranslatedNonStaticDataMemberVarInit(field) and
19+
cls.getAMember() = field
20+
}
21+
22+
override string toString() { result = cls.toString() + "::" + field.toString() }
23+
24+
final override Field getAst() { result = field }
25+
26+
final override Declaration getFunction() { result = field }
27+
28+
override Instruction getFirstInstruction(EdgeKind kind) {
29+
result = this.getInstruction(EnterFunctionTag()) and
30+
kind instanceof GotoEdge
31+
}
32+
33+
override Instruction getALastInstructionInternal() {
34+
result = this.getInstruction(ExitFunctionTag())
35+
}
36+
37+
override TranslatedElement getChild(int n) {
38+
n = 1 and
39+
result = getTranslatedInitialization(field.getInitializer().getExpr().getFullyConverted())
40+
}
41+
42+
override predicate hasInstruction(Opcode op, InstructionTag tag, CppType type) {
43+
op instanceof Opcode::EnterFunction and
44+
tag = EnterFunctionTag() and
45+
type = getVoidType()
46+
or
47+
op instanceof Opcode::AliasedDefinition and
48+
tag = AliasedDefinitionTag() and
49+
type = getUnknownType()
50+
or
51+
op instanceof Opcode::InitializeNonLocal and
52+
tag = InitializeNonLocalTag() and
53+
type = getUnknownType()
54+
or
55+
tag = ThisAddressTag() and
56+
op instanceof Opcode::VariableAddress and
57+
type = getTypeForGLValue(any(UnknownType t))
58+
or
59+
tag = InitializerStoreTag() and
60+
op instanceof Opcode::InitializeParameter and
61+
type = this.getThisType()
62+
or
63+
tag = ThisLoadTag() and
64+
op instanceof Opcode::Load and
65+
type = this.getThisType()
66+
or
67+
tag = InitializerIndirectStoreTag() and
68+
op instanceof Opcode::InitializeIndirection and
69+
type = getTypeForPRValue(cls)
70+
or
71+
op instanceof Opcode::FieldAddress and
72+
tag = InitializerFieldAddressTag() and
73+
type = getTypeForGLValue(field.getType())
74+
or
75+
op instanceof Opcode::ReturnVoid and
76+
tag = ReturnTag() and
77+
type = getVoidType()
78+
or
79+
op instanceof Opcode::AliasedUse and
80+
tag = AliasedUseTag() and
81+
type = getVoidType()
82+
or
83+
op instanceof Opcode::ExitFunction and
84+
tag = ExitFunctionTag() and
85+
type = getVoidType()
86+
}
87+
88+
override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
89+
kind instanceof GotoEdge and
90+
(
91+
tag = EnterFunctionTag() and
92+
result = this.getInstruction(AliasedDefinitionTag())
93+
or
94+
tag = AliasedDefinitionTag() and
95+
result = this.getInstruction(InitializeNonLocalTag())
96+
or
97+
tag = InitializeNonLocalTag() and
98+
result = this.getInstruction(ThisAddressTag())
99+
or
100+
tag = ThisAddressTag() and
101+
result = this.getInstruction(InitializerStoreTag())
102+
or
103+
tag = InitializerStoreTag() and
104+
result = this.getInstruction(ThisLoadTag())
105+
or
106+
tag = ThisLoadTag() and
107+
result = this.getInstruction(InitializerIndirectStoreTag())
108+
or
109+
tag = InitializerIndirectStoreTag() and
110+
result = this.getInstruction(InitializerFieldAddressTag())
111+
)
112+
or
113+
tag = InitializerFieldAddressTag() and
114+
result = this.getChild(1).getFirstInstruction(kind)
115+
or
116+
kind instanceof GotoEdge and
117+
(
118+
tag = ReturnTag() and
119+
result = this.getInstruction(AliasedUseTag())
120+
or
121+
tag = AliasedUseTag() and
122+
result = this.getInstruction(ExitFunctionTag())
123+
)
124+
}
125+
126+
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
127+
child = this.getChild(1) and
128+
result = this.getInstruction(ReturnTag()) and
129+
kind instanceof GotoEdge
130+
}
131+
132+
final override CppType getInstructionMemoryOperandType(
133+
InstructionTag tag, TypedOperandTag operandTag
134+
) {
135+
tag = AliasedUseTag() and
136+
operandTag instanceof SideEffectOperandTag and
137+
result = getUnknownType()
138+
}
139+
140+
override IRVariable getInstructionVariable(InstructionTag tag) {
141+
(
142+
tag = ThisAddressTag() or
143+
tag = InitializerStoreTag() or
144+
tag = InitializerIndirectStoreTag()
145+
) and
146+
result = getIRTempVariable(field, ThisTempVar())
147+
}
148+
149+
override Field getInstructionField(InstructionTag tag) {
150+
tag = InitializerFieldAddressTag() and
151+
result = field
152+
}
153+
154+
override predicate hasTempVariable(TempVariableTag tag, CppType type) {
155+
tag = ThisTempVar() and
156+
type = this.getThisType()
157+
}
158+
159+
/**
160+
* Holds if this variable defines or accesses variable `var` with type `type`. This includes all
161+
* parameters and local variables, plus any global variables or static data members that are
162+
* directly accessed by the function.
163+
*/
164+
final predicate hasUserVariable(Variable varUsed, CppType type) {
165+
(
166+
(
167+
varUsed instanceof GlobalOrNamespaceVariable
168+
or
169+
varUsed instanceof StaticLocalVariable
170+
or
171+
varUsed instanceof MemberVariable and not varUsed instanceof Field
172+
) and
173+
exists(VariableAccess access |
174+
access.getTarget() = varUsed and
175+
getEnclosingVariable(access) = field
176+
)
177+
or
178+
field = varUsed
179+
or
180+
varUsed.(LocalScopeVariable).getEnclosingElement*() = field
181+
or
182+
varUsed.(Parameter).getCatchBlock().getEnclosingElement*() = field
183+
) and
184+
type = getTypeForPRValue(getVariableType(varUsed))
185+
}
186+
187+
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
188+
(
189+
tag = InitializerStoreTag()
190+
or
191+
tag = ThisLoadTag()
192+
) and
193+
operandTag instanceof AddressOperandTag and
194+
result = this.getInstruction(ThisAddressTag())
195+
or
196+
(
197+
tag = InitializerIndirectStoreTag() and
198+
operandTag instanceof AddressOperandTag
199+
or
200+
tag = InitializerFieldAddressTag() and
201+
operandTag instanceof UnaryOperandTag
202+
) and
203+
result = this.getInstruction(ThisLoadTag())
204+
}
205+
206+
override Instruction getTargetAddress() {
207+
result = this.getInstruction(InitializerFieldAddressTag())
208+
}
209+
210+
override Type getTargetType() { result = field.getUnspecifiedType() }
211+
212+
final Instruction getLoadThisInstruction() { result = this.getInstruction(ThisLoadTag()) }
213+
214+
private CppType getThisType() { result = getTypeForGLValue(cls) }
215+
}
216+
217+
TranslatedNonStaticDataMemberVarInit getTranslatedFieldInit(Field field) { result.getAst() = field }

0 commit comments

Comments
 (0)