Skip to content

Commit 10ae793

Browse files
committed
C++: Add an 'EdgeKind' column to 'getFirstInstruction'.
1 parent d2e8b88 commit 10ae793

File tree

10 files changed

+421
-359
lines changed

10 files changed

+421
-359
lines changed

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ private predicate backEdgeCandidate(
285285
// is a back edge. This includes edges from `continue` and the fall-through
286286
// edge(s) after the last instruction(s) in the body.
287287
exists(TranslatedWhileStmt s |
288-
targetInstruction = s.getFirstConditionInstruction() and
288+
targetInstruction = s.getFirstConditionInstruction(_) and
289289
targetInstruction = sourceElement.getInstructionSuccessor(sourceTag, kind) and
290290
requiredAncestor = s.getBody()
291291
)
@@ -296,7 +296,7 @@ private predicate backEdgeCandidate(
296296
// { ... } while (0)` statement. Note that all `continue` statements in a
297297
// do-while loop produce forward edges.
298298
exists(TranslatedDoStmt s |
299-
targetInstruction = s.getBody().getFirstInstruction() and
299+
targetInstruction = s.getBody().getFirstInstruction(_) and
300300
targetInstruction = sourceElement.getInstructionSuccessor(sourceTag, kind) and
301301
requiredAncestor = s.getCondition()
302302
)
@@ -308,7 +308,7 @@ private predicate backEdgeCandidate(
308308
// last instruction(s) in the body. A for loop may not have a condition, in
309309
// which case `getFirstConditionInstruction` returns the body instead.
310310
exists(TranslatedForStmt s |
311-
targetInstruction = s.getFirstConditionInstruction() and
311+
targetInstruction = s.getFirstConditionInstruction(_) and
312312
targetInstruction = sourceElement.getInstructionSuccessor(sourceTag, kind) and
313313
(
314314
requiredAncestor = s.getUpdate()
@@ -322,7 +322,7 @@ private predicate backEdgeCandidate(
322322
// Any edge from within the update of the loop to the condition of
323323
// the loop is a back edge.
324324
exists(TranslatedRangeBasedForStmt s |
325-
targetInstruction = s.getCondition().getFirstInstruction() and
325+
targetInstruction = s.getCondition().getFirstInstruction(_) and
326326
targetInstruction = sourceElement.getInstructionSuccessor(sourceTag, kind) and
327327
requiredAncestor = s.getUpdate()
328328
)

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

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ abstract class TranslatedCall extends TranslatedExpr {
4040
id = this.getNumberOfArguments() and result = this.getSideEffects()
4141
}
4242

43-
final override Instruction getFirstInstruction() {
43+
final override Instruction getFirstInstruction(EdgeKind kind) {
4444
if exists(this.getQualifier())
45-
then result = this.getQualifier().getFirstInstruction()
46-
else result = this.getFirstCallTargetInstruction()
45+
then result = this.getQualifier().getFirstInstruction(kind)
46+
else result = this.getFirstCallTargetInstruction(kind)
4747
}
4848

4949
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -53,19 +53,18 @@ abstract class TranslatedCall extends TranslatedExpr {
5353
}
5454

5555
override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) {
56-
kind instanceof GotoEdge and
57-
(
58-
child = this.getQualifier() and
59-
result = this.getFirstCallTargetInstruction()
60-
or
61-
child = this.getCallTarget() and
62-
result = this.getFirstArgumentOrCallInstruction()
63-
or
64-
exists(int argIndex |
65-
child = this.getArgument(argIndex) and
66-
if exists(this.getArgument(argIndex + 1))
67-
then result = this.getArgument(argIndex + 1).getFirstInstruction()
68-
else result = this.getInstruction(CallTag())
56+
child = this.getQualifier() and
57+
result = this.getFirstCallTargetInstruction(kind)
58+
or
59+
child = this.getCallTarget() and
60+
result = this.getFirstArgumentOrCallInstruction(kind)
61+
or
62+
exists(int argIndex |
63+
child = this.getArgument(argIndex) and
64+
if exists(this.getArgument(argIndex + 1))
65+
then result = this.getArgument(argIndex + 1).getFirstInstruction(kind)
66+
else (
67+
result = this.getInstruction(CallTag()) and kind instanceof GotoEdge
6968
)
7069
)
7170
or
@@ -81,9 +80,8 @@ abstract class TranslatedCall extends TranslatedExpr {
8180
}
8281

8382
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
84-
kind instanceof GotoEdge and
8583
tag = CallTag() and
86-
result = this.getSideEffects().getFirstInstruction()
84+
result = this.getSideEffects().getFirstInstruction(kind)
8785
}
8886

8987
override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
@@ -125,8 +123,8 @@ abstract class TranslatedCall extends TranslatedExpr {
125123
* it can be overridden by a subclass for cases where there is a call target
126124
* that is not computed from an expression (e.g. a direct call).
127125
*/
128-
Instruction getFirstCallTargetInstruction() {
129-
result = this.getCallTarget().getFirstInstruction()
126+
Instruction getFirstCallTargetInstruction(EdgeKind kind) {
127+
result = this.getCallTarget().getFirstInstruction(kind)
130128
}
131129

132130
/**
@@ -163,10 +161,12 @@ abstract class TranslatedCall extends TranslatedExpr {
163161
* If there are any arguments, gets the first instruction of the first
164162
* argument. Otherwise, returns the call instruction.
165163
*/
166-
final Instruction getFirstArgumentOrCallInstruction() {
164+
final Instruction getFirstArgumentOrCallInstruction(EdgeKind kind) {
167165
if this.hasArguments()
168-
then result = this.getArgument(0).getFirstInstruction()
169-
else result = this.getInstruction(CallTag())
166+
then result = this.getArgument(0).getFirstInstruction(kind)
167+
else (
168+
kind instanceof GotoEdge and result = this.getInstruction(CallTag())
169+
)
170170
}
171171

172172
/**
@@ -211,7 +211,7 @@ abstract class TranslatedSideEffects extends TranslatedElement {
211211
exists(int i |
212212
this.getChild(i) = te and
213213
if exists(this.getChild(i + 1))
214-
then kind instanceof GotoEdge and result = this.getChild(i + 1).getFirstInstruction()
214+
then result = this.getChild(i + 1).getFirstInstruction(kind)
215215
else result = this.getParent().getChildSuccessor(this, kind)
216216
)
217217
}
@@ -220,12 +220,12 @@ abstract class TranslatedSideEffects extends TranslatedElement {
220220
none()
221221
}
222222

223-
final override Instruction getFirstInstruction() {
224-
result = this.getChild(0).getFirstInstruction()
223+
final override Instruction getFirstInstruction(EdgeKind kind) {
224+
result = this.getChild(0).getFirstInstruction(kind)
225225
or
226226
// Some functions, like `std::move()`, have no side effects whatsoever.
227227
not exists(this.getChild(0)) and
228-
result = this.getParent().getChildSuccessor(this, any(GotoEdge edge))
228+
result = this.getParent().getChildSuccessor(this, kind)
229229
}
230230

231231
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
@@ -240,8 +240,9 @@ abstract class TranslatedSideEffects extends TranslatedElement {
240240
* (`TranslatedAllocatorCall`).
241241
*/
242242
abstract class TranslatedDirectCall extends TranslatedCall {
243-
final override Instruction getFirstCallTargetInstruction() {
244-
result = this.getInstruction(CallTargetTag())
243+
final override Instruction getFirstCallTargetInstruction(EdgeKind kind) {
244+
result = this.getInstruction(CallTargetTag()) and
245+
kind instanceof GotoEdge
245246
}
246247

247248
final override Instruction getCallTargetResult() { result = this.getInstruction(CallTargetTag()) }
@@ -258,8 +259,7 @@ abstract class TranslatedDirectCall extends TranslatedCall {
258259
result = TranslatedCall.super.getInstructionSuccessor(tag, kind)
259260
or
260261
tag = CallTargetTag() and
261-
kind instanceof GotoEdge and
262-
result = this.getFirstArgumentOrCallInstruction()
262+
result = this.getFirstArgumentOrCallInstruction(kind)
263263
}
264264
}
265265

@@ -383,8 +383,9 @@ abstract class TranslatedSideEffect extends TranslatedElement {
383383

384384
final override Instruction getChildSuccessor(TranslatedElement child, EdgeKind kind) { none() }
385385

386-
final override Instruction getFirstInstruction() {
387-
result = this.getInstruction(OnlyInstructionTag())
386+
final override Instruction getFirstInstruction(EdgeKind kind) {
387+
result = this.getInstruction(OnlyInstructionTag()) and
388+
kind instanceof GotoEdge
388389
}
389390

390391
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType type) {

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

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ abstract class TranslatedFlexibleCondition extends TranslatedCondition, Conditio
4444

4545
final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() }
4646

47-
final override Instruction getFirstInstruction() {
48-
result = this.getOperand().getFirstInstruction()
47+
final override Instruction getFirstInstruction(EdgeKind kind) {
48+
result = this.getOperand().getFirstInstruction(kind)
4949
}
5050

5151
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -92,8 +92,8 @@ abstract class TranslatedBinaryLogicalOperation extends TranslatedNativeConditio
9292
id = 1 and result = this.getRightOperand()
9393
}
9494

95-
final override Instruction getFirstInstruction() {
96-
result = this.getLeftOperand().getFirstInstruction()
95+
final override Instruction getFirstInstruction(EdgeKind kind) {
96+
result = this.getLeftOperand().getFirstInstruction(kind)
9797
}
9898

9999
final override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
@@ -116,7 +116,7 @@ class TranslatedLogicalAndExpr extends TranslatedBinaryLogicalOperation {
116116

117117
override Instruction getChildTrueSuccessor(TranslatedCondition child) {
118118
child = this.getLeftOperand() and
119-
result = this.getRightOperand().getFirstInstruction()
119+
result = this.getRightOperand().getFirstInstruction(any(GotoEdge edge))
120120
or
121121
child = this.getRightOperand() and
122122
result = this.getConditionContext().getChildTrueSuccessor(this)
@@ -138,7 +138,7 @@ class TranslatedLogicalOrExpr extends TranslatedBinaryLogicalOperation {
138138

139139
override Instruction getChildFalseSuccessor(TranslatedCondition child) {
140140
child = this.getLeftOperand() and
141-
result = this.getRightOperand().getFirstInstruction()
141+
result = this.getRightOperand().getFirstInstruction(any(GotoEdge edge))
142142
or
143143
child = this.getRightOperand() and
144144
result = this.getConditionContext().getChildFalseSuccessor(this)
@@ -150,7 +150,9 @@ class TranslatedValueCondition extends TranslatedCondition, TTranslatedValueCond
150150

151151
override TranslatedElement getChild(int id) { id = 0 and result = this.getValueExpr() }
152152

153-
override Instruction getFirstInstruction() { result = this.getValueExpr().getFirstInstruction() }
153+
override Instruction getFirstInstruction(EdgeKind kind) {
154+
result = this.getValueExpr().getFirstInstruction(kind)
155+
}
154156

155157
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
156158
tag = ValueConditionConditionalBranchTag() and

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,9 @@ class TranslatedStaticLocalVariableDeclarationEntry extends TranslatedDeclaratio
147147
type = getBoolType()
148148
}
149149

150-
final override Instruction getFirstInstruction() {
151-
result = this.getInstruction(DynamicInitializationFlagAddressTag())
150+
final override Instruction getFirstInstruction(EdgeKind kind) {
151+
result = this.getInstruction(DynamicInitializationFlagAddressTag()) and
152+
kind instanceof GotoEdge
152153
}
153154

154155
final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
@@ -166,7 +167,7 @@ class TranslatedStaticLocalVariableDeclarationEntry extends TranslatedDeclaratio
166167
result = this.getParent().getChildSuccessor(this, any(GotoEdge edge))
167168
or
168169
kind instanceof FalseEdge and
169-
result = this.getInitialization().getFirstInstruction()
170+
result = this.getInitialization().getFirstInstruction(any(GotoEdge edge))
170171
)
171172
or
172173
tag = DynamicInitializationFlagConstantTag() and

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -827,9 +827,10 @@ abstract class TranslatedElement extends TTranslatedElement {
827827
Location getLocation() { result = this.getAst().getLocation() }
828828

829829
/**
830-
* Get the first instruction to be executed in the evaluation of this element.
830+
* Get the first instruction to be executed in the evaluation of this
831+
* element when the edge kind is `kind`.
831832
*/
832-
abstract Instruction getFirstInstruction();
833+
abstract Instruction getFirstInstruction(EdgeKind kind);
833834

834835
/**
835836
* Get the immediate child elements of this element.

0 commit comments

Comments
 (0)