Skip to content

Commit bd89ee1

Browse files
committed
C++: Add InitializeDynamicAllocation instruction to NewExpr and NewArrayExpr
1 parent 688464a commit bd89ee1

File tree

3 files changed

+89
-51
lines changed

3 files changed

+89
-51
lines changed

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

Lines changed: 78 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ private import InstructionTag
77
private import TranslatedElement
88
private import TranslatedExpr
99
private import TranslatedFunction
10+
private import semmle.code.cpp.models.implementations.Allocation
1011

1112
/**
1213
* The IR translation of a call to a function. The call may be from an actual
@@ -206,7 +207,44 @@ abstract class TranslatedCall extends TranslatedExpr {
206207

207208
predicate hasPreciseSideEffect() { exists(getSideEffects()) }
208209

209-
TranslatedSideEffects getSideEffects() { result.getCall() = expr }
210+
final TranslatedSideEffects getSideEffects() { result.getExpr() = expr }
211+
}
212+
213+
abstract class TranslatedSideEffects extends TranslatedElement {
214+
abstract Expr getExpr();
215+
216+
final override Locatable getAST() { result = getExpr() }
217+
218+
final override Function getFunction() { result = getExpr().getEnclosingFunction() }
219+
220+
override TranslatedElement getChild(int i) {
221+
result =
222+
rank[i + 1](TranslatedSideEffect tse, int isWrite, int index |
223+
(
224+
tse.getCall() = getExpr() and
225+
tse.getArgumentIndex() = index and
226+
if tse.isWrite() then isWrite = 1 else isWrite = 0
227+
)
228+
|
229+
tse order by isWrite, index
230+
)
231+
}
232+
233+
final override Instruction getChildSuccessor(TranslatedElement te) {
234+
exists(int i |
235+
getChild(i) = te and
236+
if exists(getChild(i + 1))
237+
then result = getChild(i + 1).getFirstInstruction()
238+
else result = getParent().getChildSuccessor(this)
239+
)
240+
}
241+
242+
/**
243+
* Gets the `TranslatedFunction` containing this expression.
244+
*/
245+
final TranslatedFunction getEnclosingFunction() {
246+
result = getTranslatedFunction(getExpr().getEnclosingFunction())
247+
}
210248
}
211249

212250
/**
@@ -308,56 +346,27 @@ class TranslatedStructorCall extends TranslatedFunctionCall {
308346
override predicate hasQualifier() { any() }
309347
}
310348

311-
class TranslatedSideEffects extends TranslatedElement, TTranslatedSideEffects {
312-
Call expr;
313-
314-
TranslatedSideEffects() { this = TTranslatedSideEffects(expr) }
315-
316-
override string toString() { result = "(side effects for " + expr.toString() + ")" }
349+
abstract class TranslatedAllocationSideEffects extends TranslatedSideEffects,
350+
TTranslatedAllocationSideEffects {
351+
AllocationExpr expr;
317352

318-
override Locatable getAST() { result = expr }
353+
TranslatedAllocationSideEffects() { this = TTranslatedAllocationSideEffects(expr) }
319354

320-
Call getCall() { result = expr }
355+
final override AllocationExpr getExpr() { result = expr }
321356

322-
override TranslatedElement getChild(int i) {
323-
result =
324-
rank[i + 1](TranslatedSideEffect tse, int isWrite, int index |
325-
(
326-
tse.getCall() = getCall() and
327-
tse.getArgumentIndex() = index and
328-
if tse.isWrite() then isWrite = 1 else isWrite = 0
329-
)
330-
|
331-
tse order by isWrite, index
332-
)
333-
}
357+
override string toString() { result = "(allocation side effects for " + expr.toString() + ")" }
334358

335-
override Instruction getChildSuccessor(TranslatedElement te) {
336-
exists(int i |
337-
getChild(i) = te and
338-
if exists(getChild(i + 1))
339-
then result = getChild(i + 1).getFirstInstruction()
340-
else result = getParent().getChildSuccessor(this)
341-
)
342-
}
359+
override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
343360

344361
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
345-
expr.getTarget() instanceof AllocationFunction and
346362
opcode instanceof Opcode::InitializeDynamicAllocation and
347363
tag = OnlyInstructionTag() and
348364
type = getUnknownType()
349365
}
350366

351-
override Instruction getFirstInstruction() {
352-
if expr.getTarget() instanceof AllocationFunction
353-
then result = getInstruction(OnlyInstructionTag())
354-
else result = getChild(0).getFirstInstruction()
355-
}
356-
357367
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
358368
tag = OnlyInstructionTag() and
359369
kind = gotoEdge() and
360-
expr.getTarget() instanceof AllocationFunction and
361370
if exists(getChild(0))
362371
then result = getChild(0).getFirstInstruction()
363372
else result = getParent().getChildSuccessor(this)
@@ -368,26 +377,48 @@ class TranslatedSideEffects extends TranslatedElement, TTranslatedSideEffects {
368377
operandTag = addressOperand() and
369378
result = getPrimaryInstructionForSideEffect(OnlyInstructionTag())
370379
}
380+
}
381+
382+
class TranslatedCallAllocationSideEffects extends TranslatedAllocationSideEffects {
383+
override CallAllocationExpr expr;
371384

372385
override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
373386
tag = OnlyInstructionTag() and
374387
result = getTranslatedExpr(expr).getInstruction(CallTag())
375388
}
389+
}
376390

377-
/**
378-
* Gets the `TranslatedFunction` containing this expression.
379-
*/
380-
final TranslatedFunction getEnclosingFunction() {
381-
result = getTranslatedFunction(expr.getEnclosingFunction())
391+
class TranslatedNewAllocationSideEffects extends TranslatedAllocationSideEffects {
392+
override NewAllocationExpr expr;
393+
394+
override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
395+
tag = OnlyInstructionTag() and
396+
result = getTranslatedAllocatorCall(expr).getInstruction(CallTag())
382397
}
398+
}
383399

384-
/**
385-
* Gets the `Function` containing this expression.
386-
*/
387-
override Function getFunction() { result = expr.getEnclosingFunction() }
400+
class TranslatedCallSideEffects extends TranslatedSideEffects, TTranslatedCallSideEffects {
401+
Call expr;
402+
403+
TranslatedCallSideEffects() { this = TTranslatedCallSideEffects(expr) }
404+
405+
override string toString() { result = "(side effects for " + expr.toString() + ")" }
406+
407+
override Call getExpr() { result = expr }
408+
409+
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) { none() }
410+
411+
override Instruction getFirstInstruction() { result = getChild(0).getFirstInstruction() }
412+
413+
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
414+
415+
override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
416+
tag = OnlyInstructionTag() and
417+
result = getTranslatedExpr(expr).getInstruction(CallTag())
418+
}
388419
}
389420

390-
class TranslatedStructorCallSideEffects extends TranslatedSideEffects {
421+
class TranslatedStructorCallSideEffects extends TranslatedCallSideEffects {
391422
TranslatedStructorCallSideEffects() { getParent().(TranslatedStructorCall).hasQualifier() }
392423

393424
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType t) {

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -442,11 +442,13 @@ newtype TTranslatedElement =
442442
// The declaration/initialization part of a `ConditionDeclExpr`
443443
TTranslatedConditionDecl(ConditionDeclExpr expr) { not ignoreExpr(expr) } or
444444
// The side effects of a `Call`
445-
TTranslatedSideEffects(Call expr) {
445+
TTranslatedCallSideEffects(Call expr) {
446446
exists(TTranslatedArgumentSideEffect(expr, _, _, _)) or
447-
expr instanceof ConstructorCall or
448-
expr.getTarget() instanceof AllocationFunction
449-
} or // A precise side effect of an argument to a `Call`
447+
expr instanceof ConstructorCall
448+
} or
449+
// The side effects of an allocation, i.e. `new`, `new[]` or `malloc`
450+
TTranslatedAllocationSideEffects(AllocationExpr expr) or
451+
// A precise side effect of an argument to a `Call`
450452
TTranslatedArgumentSideEffect(Call call, Expr expr, int n, boolean isWrite) {
451453
(
452454
expr = call.getArgument(n).getFullyConverted()

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1649,6 +1649,11 @@ class TranslatedAllocatorCall extends TTranslatedAllocatorCall, TranslatedDirect
16491649

16501650
final override int getNumberOfArguments() {
16511651
result = expr.getAllocatorCall().getNumberOfArguments()
1652+
or
1653+
// Make sure there's a result even when there is no allocator, as otherwise
1654+
// TranslatedCall::getChild() will not return the side effects for this call.
1655+
not exists(expr.getAllocatorCall()) and
1656+
result = 0
16521657
}
16531658

16541659
final override TranslatedExpr getArgument(int index) {

0 commit comments

Comments
 (0)