Skip to content

Commit ba72a1c

Browse files
author
Dave Bartolomeo
committed
Make TranslatedSideEffect abstract
This is step two of fixing the ordering of call side effects. This commit refactors the existing `TranslatedSideEffect` class into an abstract `TranslatedSideEffect` class, which contains functionality common to all kinds of side effect, and a concrete `TranslatedArgumentSideEffect` class, which is the implementation of argument side effects. A future commit will add additional concrete classes for conservative call side effects and allocation side effects. This change has zero diffs to the generated IR.
1 parent 47e16b0 commit ba72a1c

File tree

1 file changed

+72
-25
lines changed

1 file changed

+72
-25
lines changed

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

Lines changed: 72 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -219,14 +219,11 @@ abstract class TranslatedSideEffects extends TranslatedElement {
219219

220220
override TranslatedElement getChild(int i) {
221221
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-
)
222+
rank[i + 1](TranslatedSideEffect tse, int group, int indexInGroup |
223+
tse.getPrimaryExpr() = getExpr() and
224+
tse.sortOrder(group, indexInGroup)
228225
|
229-
tse order by isWrite, index
226+
tse order by group, indexInGroup
230227
)
231228
}
232229

@@ -445,23 +442,86 @@ class TranslatedStructorCallSideEffects extends TranslatedCallSideEffects {
445442
}
446443
}
447444

448-
class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEffect {
445+
/** Returns the sort group index for argument read side effects. */
446+
private int argumentReadGroup() { result = 1 }
447+
448+
/** Returns the sort group index for conservative call side effects. */
449+
private int callSideEffectGroup() {
450+
result = 0 // Make this group first for now to preserve the existing ordering
451+
}
452+
453+
/** Returns the sort group index for argument write side effects. */
454+
private int argumentWriteGroup() { result = 2 }
455+
456+
/** Returns the sort group index for dynamic allocation side effects. */
457+
private int initializeAllocationGroup() { result = 3 }
458+
459+
/**
460+
* The IR translation of a single side effect of a call.
461+
*/
462+
abstract class TranslatedSideEffect extends TranslatedElement {
463+
final override TranslatedElement getChild(int n) { none() }
464+
465+
final override Instruction getChildSuccessor(TranslatedElement child) { none() }
466+
467+
final override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
468+
469+
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
470+
tag = OnlyInstructionTag() and
471+
sideEffectInstruction(opcode, type)
472+
}
473+
474+
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
475+
result = getParent().getChildSuccessor(this) and
476+
tag = OnlyInstructionTag() and
477+
kind instanceof GotoEdge
478+
}
479+
480+
/**
481+
* Gets the expression that caused this side effect.
482+
*
483+
* All side effects with the same `getPrimaryExpr()` will appear in the same contiguous sequence
484+
* in the IR.
485+
*/
486+
abstract Expr getPrimaryExpr();
487+
488+
/**
489+
* Gets the order in which this side effect should be sorted with respect to other side effects
490+
* for the same expression.
491+
*
492+
* Side effects are sorted first by `group`, and then by `indexInGroup`.
493+
*/
494+
abstract predicate sortOrder(int group, int indexInGroup);
495+
496+
/**
497+
* Gets the opcode and result type for the side effect instruction.
498+
*/
499+
abstract predicate sideEffectInstruction(Opcode opcode, CppType type);
500+
}
501+
502+
/**
503+
* The IR translation of a single argument side effect for a call.
504+
*/
505+
class TranslatedArgumentSideEffect extends TranslatedSideEffect, TTranslatedArgumentSideEffect {
449506
Call call;
450507
Expr arg;
451508
int index;
452509
SideEffectOpcode sideEffectOpcode;
453510

454-
TranslatedSideEffect() {
511+
TranslatedArgumentSideEffect() {
455512
this = TTranslatedArgumentSideEffect(call, arg, index, sideEffectOpcode)
456513
}
457514

458515
override Locatable getAST() { result = arg }
459516

460517
Expr getExpr() { result = arg }
461518

462-
Call getCall() { result = call }
519+
override Call getPrimaryExpr() { result = call }
463520

464-
int getArgumentIndex() { result = index }
521+
override predicate sortOrder(int group, int indexInGroup) {
522+
indexInGroup = index and
523+
if isWrite() then group = argumentWriteGroup() else group = argumentReadGroup()
524+
}
465525

466526
predicate isWrite() { sideEffectOpcode instanceof WriteSideEffectOpcode }
467527

@@ -473,14 +533,7 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
473533
result = "(read side effect for " + arg.toString() + ")"
474534
}
475535

476-
override TranslatedElement getChild(int n) { none() }
477-
478-
override Instruction getChildSuccessor(TranslatedElement child) { none() }
479-
480-
override Instruction getFirstInstruction() { result = getInstruction(OnlyInstructionTag()) }
481-
482-
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {
483-
tag = OnlyInstructionTag() and
536+
override predicate sideEffectInstruction(Opcode opcode, CppType type) {
484537
opcode = sideEffectOpcode and
485538
(
486539
isWrite() and
@@ -505,12 +558,6 @@ class TranslatedSideEffect extends TranslatedElement, TTranslatedArgumentSideEff
505558
)
506559
}
507560

508-
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
509-
result = getParent().getChildSuccessor(this) and
510-
tag = OnlyInstructionTag() and
511-
kind instanceof GotoEdge
512-
}
513-
514561
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
515562
tag instanceof OnlyInstructionTag and
516563
operandTag instanceof AddressOperandTag and

0 commit comments

Comments
 (0)