Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6089172

Browse files
author
Robert Marsh
committed
C++: escape analysis for this parameters
1 parent 466e110 commit 6089172

4 files changed

Lines changed: 270 additions & 158 deletions

File tree

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/internal/AliasAnalysis.qll

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,19 @@ predicate operandIsPropagated(Operand operand, IntValue bitOffset) {
153153
operandIsPropagated(operand, _) and not resultEscapes(operand.getUseInstruction())
154154
or
155155
// The address is passed as an argument to a function from which it does not escape
156-
exists(CallInstruction ci, FunctionIR f, InitializeParameterInstruction ipi |
156+
exists(CallInstruction ci, FunctionIR f, Instruction init |
157157
ci = operand.getUseInstruction() and
158158
f.getFunction() = ci.getStaticCallTarget() and
159-
ipi.getParameter() = f.getFunction().getParameter(operand.(PositionalArgumentOperand).getIndex()) and
160-
not resultEscapesNonReturn(ipi) and
161159
(
162-
not resultReturned(ipi)
160+
init.(InitializeParameterInstruction).getParameter() = f.getFunction().getParameter(operand.(PositionalArgumentOperand).getIndex())
161+
or
162+
init instanceof InitializeThisInstruction and
163+
init.getEnclosingFunctionIR() = f and
164+
operand instanceof ThisArgumentOperand
165+
) and
166+
not resultEscapesNonReturn(init) and
167+
(
168+
not resultReturned(init)
163169
or
164170
not resultEscapes(operand.getUseInstruction())
165171
)
@@ -179,11 +185,17 @@ predicate operandEscapesNonReturn(Operand operand) {
179185
not resultEscapesNonReturn(operand.getUseInstruction())
180186
or
181187
// The operand is used in a function call from which the operand does not escape
182-
exists(CallInstruction ci, FunctionIR f, InitializeParameterInstruction ipi |
188+
exists(CallInstruction ci, FunctionIR f, Instruction init |
183189
ci = operand.getUseInstruction() and
184190
f.getFunction() = ci.getStaticCallTarget() and
185-
ipi.getParameter() = f.getFunction().getParameter(operand.(PositionalArgumentOperand).getIndex()) and
186-
not resultEscapesNonReturn(ipi) and
191+
(
192+
init.(InitializeParameterInstruction).getParameter() = f.getFunction().getParameter(operand.(PositionalArgumentOperand).getIndex())
193+
or
194+
init instanceof InitializeThisInstruction and
195+
init.getEnclosingFunctionIR() = f and
196+
operand instanceof ThisArgumentOperand
197+
) and
198+
not resultEscapesNonReturn(init) and
187199
not resultEscapesNonReturn(ci)
188200
) or
189201
operand instanceof ReturnValueOperand
@@ -203,6 +215,20 @@ predicate operandReturned(Operand operand) {
203215
resultReturned(ci)
204216
)
205217
or
218+
exists(CallInstruction ci, FunctionIR f, Instruction init |
219+
ci = operand.getUseInstruction() and
220+
f.getFunction() = ci.getStaticCallTarget() and
221+
(
222+
init.(InitializeParameterInstruction).getParameter() = f.getFunction().getParameter(operand.(PositionalArgumentOperand).getIndex())
223+
or
224+
init instanceof InitializeThisInstruction and
225+
init.getEnclosingFunctionIR() = f and
226+
operand instanceof ThisArgumentOperand
227+
) and
228+
resultReturned(init) and
229+
resultReturned(ci)
230+
)
231+
or
206232
// The address is returned
207233
operand instanceof ReturnValueOperand
208234
}
@@ -271,11 +297,17 @@ predicate resultPointsTo(Instruction instr, IRVariable var, IntValue bitOffset)
271297
(
272298
operandIsPropagated(operand, propagatedBitOffset)
273299
or
274-
exists(CallInstruction ci, FunctionIR f, InitializeParameterInstruction ipi |
300+
exists(CallInstruction ci, FunctionIR f, Instruction init |
275301
ci = operand.getUseInstruction() and
276302
f.getFunction() = ci.getStaticCallTarget() and
277-
ipi.getParameter() = f.getFunction().getParameter(operand.(PositionalArgumentOperand).getIndex()) and
278-
resultReturned(ipi) and
303+
(
304+
init.(InitializeParameterInstruction).getParameter() = f.getFunction().getParameter(operand.(PositionalArgumentOperand).getIndex())
305+
or
306+
init instanceof InitializeThisInstruction and
307+
init.getEnclosingFunctionIR() = f and
308+
operand instanceof ThisArgumentOperand
309+
) and
310+
resultReturned(init) and
279311
propagatedBitOffset = Ints::unknown()
280312
)
281313
) and

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/internal/AliasAnalysis.qll

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,19 @@ predicate operandIsPropagated(Operand operand, IntValue bitOffset) {
153153
operandIsPropagated(operand, _) and not resultEscapes(operand.getUseInstruction())
154154
or
155155
// The address is passed as an argument to a function from which it does not escape
156-
exists(CallInstruction ci, FunctionIR f, InitializeParameterInstruction ipi |
156+
exists(CallInstruction ci, FunctionIR f, Instruction init |
157157
ci = operand.getUseInstruction() and
158158
f.getFunction() = ci.getStaticCallTarget() and
159-
ipi.getParameter() = f.getFunction().getParameter(operand.(PositionalArgumentOperand).getIndex()) and
160-
not resultEscapesNonReturn(ipi) and
161159
(
162-
not resultReturned(ipi)
160+
init.(InitializeParameterInstruction).getParameter() = f.getFunction().getParameter(operand.(PositionalArgumentOperand).getIndex())
161+
or
162+
init instanceof InitializeThisInstruction and
163+
init.getEnclosingFunctionIR() = f and
164+
operand instanceof ThisArgumentOperand
165+
) and
166+
not resultEscapesNonReturn(init) and
167+
(
168+
not resultReturned(init)
163169
or
164170
not resultEscapes(operand.getUseInstruction())
165171
)
@@ -179,11 +185,17 @@ predicate operandEscapesNonReturn(Operand operand) {
179185
not resultEscapesNonReturn(operand.getUseInstruction())
180186
or
181187
// The operand is used in a function call from which the operand does not escape
182-
exists(CallInstruction ci, FunctionIR f, InitializeParameterInstruction ipi |
188+
exists(CallInstruction ci, FunctionIR f, Instruction init |
183189
ci = operand.getUseInstruction() and
184190
f.getFunction() = ci.getStaticCallTarget() and
185-
ipi.getParameter() = f.getFunction().getParameter(operand.(PositionalArgumentOperand).getIndex()) and
186-
not resultEscapesNonReturn(ipi) and
191+
(
192+
init.(InitializeParameterInstruction).getParameter() = f.getFunction().getParameter(operand.(PositionalArgumentOperand).getIndex())
193+
or
194+
init instanceof InitializeThisInstruction and
195+
init.getEnclosingFunctionIR() = f and
196+
operand instanceof ThisArgumentOperand
197+
) and
198+
not resultEscapesNonReturn(init) and
187199
not resultEscapesNonReturn(ci)
188200
) or
189201
operand instanceof ReturnValueOperand
@@ -203,6 +215,20 @@ predicate operandReturned(Operand operand) {
203215
resultReturned(ci)
204216
)
205217
or
218+
exists(CallInstruction ci, FunctionIR f, Instruction init |
219+
ci = operand.getUseInstruction() and
220+
f.getFunction() = ci.getStaticCallTarget() and
221+
(
222+
init.(InitializeParameterInstruction).getParameter() = f.getFunction().getParameter(operand.(PositionalArgumentOperand).getIndex())
223+
or
224+
init instanceof InitializeThisInstruction and
225+
init.getEnclosingFunctionIR() = f and
226+
operand instanceof ThisArgumentOperand
227+
) and
228+
resultReturned(init) and
229+
resultReturned(ci)
230+
)
231+
or
206232
// The address is returned
207233
operand instanceof ReturnValueOperand
208234
}
@@ -271,11 +297,17 @@ predicate resultPointsTo(Instruction instr, IRVariable var, IntValue bitOffset)
271297
(
272298
operandIsPropagated(operand, propagatedBitOffset)
273299
or
274-
exists(CallInstruction ci, FunctionIR f, InitializeParameterInstruction ipi |
300+
exists(CallInstruction ci, FunctionIR f, Instruction init |
275301
ci = operand.getUseInstruction() and
276302
f.getFunction() = ci.getStaticCallTarget() and
277-
ipi.getParameter() = f.getFunction().getParameter(operand.(PositionalArgumentOperand).getIndex()) and
278-
resultReturned(ipi) and
303+
(
304+
init.(InitializeParameterInstruction).getParameter() = f.getFunction().getParameter(operand.(PositionalArgumentOperand).getIndex())
305+
or
306+
init instanceof InitializeThisInstruction and
307+
init.getEnclosingFunctionIR() = f and
308+
operand instanceof ThisArgumentOperand
309+
) and
310+
resultReturned(init) and
279311
propagatedBitOffset = Ints::unknown()
280312
)
281313
) and

cpp/ql/test/library-tests/ir/escape/escape.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,21 @@ struct Derived : Intermediate1, Intermediate2 {
6666
float d;
6767
};
6868

69+
class C;
70+
71+
void CEscapes(C *no_c);
72+
73+
class C {
74+
public:
75+
void ThisEscapes() {
76+
CEscapes(this);
77+
}
78+
79+
C *ThisReturned() {
80+
return this;
81+
}
82+
};
83+
6984
void Escape()
7085
{
7186
int no_result;
@@ -169,4 +184,24 @@ void Escape()
169184

170185
int no_ssa_passByRef7;
171186
ReturnReference(no_ssa_passByRef7);
187+
188+
C no_ssa_c;
189+
190+
no_ssa_c.ThisReturned();
191+
192+
C c;
193+
194+
c.ThisEscapes();
195+
196+
C c2;
197+
198+
CEscapes(&c2);
199+
200+
C c3;
201+
202+
c3.ThisReturned()->ThisEscapes();
203+
204+
C c4;
205+
206+
CEscapes(c4.ThisReturned());
172207
}

0 commit comments

Comments
 (0)