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

Skip to content

Commit fa2ef62

Browse files
C++: Rationalize RegisterOperand vs. MemoryOperand
This change does some shuffling to make the distinction between memory operands and register operands more clear in the IR API. First, any given type that extends `Operand` is now either always a `MemoryOperand` or always a `RegisterOperand`. This required getting rid of `CopySourceOperand`, which was used for both the `CopyValue` instruction (as a `RegisterOperand`) and for the `Load` instruction (as a `MemoryOperand`). `CopyValue` is now just a `UnaryInstruction`, `Store` has a `StoreValueOperand` (`RegisterOperand`), and all of the instructions that read a value from memory indirectly (`Load`, `ReturnValue`, and `ThrowValue`) all now have a `LoadOperand` (`MemoryOperand`). There are no diffs in the IR output for this commit, but this change is required for a subsequent commit that will make each `MemoryOperand` have a `Type`, which in turn is needed to fix a critical bug in aliased SSA construction.
1 parent 14bdea1 commit fa2ef62

15 files changed

Lines changed: 320 additions & 316 deletions

File tree

cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ abstract class BuiltInOpcode extends Opcode {}
105105

106106
abstract class SideEffectOpcode extends Opcode {}
107107

108+
/**
109+
* An opcode that reads a value from memory.
110+
*/
111+
abstract class OpcodeWithLoad extends MemoryAccessOpcode {}
112+
108113
/**
109114
* An opcode that reads from a set of memory locations as a side effect.
110115
*/
@@ -133,10 +138,10 @@ module Opcode {
133138
class InitializeThis extends Opcode, TInitializeThis { override final string toString() { result = "InitializeThis" } }
134139
class EnterFunction extends Opcode, TEnterFunction { override final string toString() { result = "EnterFunction" } }
135140
class ExitFunction extends Opcode, TExitFunction { override final string toString() { result = "ExitFunction" } }
136-
class ReturnValue extends ReturnOpcode, MemoryAccessOpcode, TReturnValue { override final string toString() { result = "ReturnValue" } }
141+
class ReturnValue extends ReturnOpcode, OpcodeWithLoad, TReturnValue { override final string toString() { result = "ReturnValue" } }
137142
class ReturnVoid extends ReturnOpcode, TReturnVoid { override final string toString() { result = "ReturnVoid" } }
138-
class CopyValue extends CopyOpcode, TCopyValue { override final string toString() { result = "CopyValue" } }
139-
class Load extends CopyOpcode, MemoryAccessOpcode, TLoad { override final string toString() { result = "Load" } }
143+
class CopyValue extends UnaryOpcode, CopyOpcode, TCopyValue { override final string toString() { result = "CopyValue" } }
144+
class Load extends CopyOpcode, OpcodeWithLoad, TLoad { override final string toString() { result = "Load" } }
140145
class Store extends CopyOpcode, MemoryAccessOpcode, TStore { override final string toString() { result = "Store" } }
141146
class Add extends BinaryOpcode, TAdd { override final string toString() { result = "Add" } }
142147
class Sub extends BinaryOpcode, TSub { override final string toString() { result = "Sub" } }
@@ -177,7 +182,7 @@ module Opcode {
177182
class Call extends Opcode, TCall { override final string toString() { result = "Call" } }
178183
class CatchByType extends CatchOpcode, TCatchByType { override final string toString() { result = "CatchByType" } }
179184
class CatchAny extends CatchOpcode, TCatchAny { override final string toString() { result = "CatchAny" } }
180-
class ThrowValue extends ThrowOpcode, MemoryAccessOpcode, TThrowValue { override final string toString() { result = "ThrowValue" } }
185+
class ThrowValue extends ThrowOpcode, OpcodeWithLoad, TThrowValue { override final string toString() { result = "ThrowValue" } }
181186
class ReThrow extends ThrowOpcode, TReThrow { override final string toString() { result = "ReThrow" } }
182187
class Unwind extends Opcode, TUnwind { override final string toString() { result = "Unwind" } }
183188
class UnmodeledDefinition extends Opcode, TUnmodeledDefinition { override final string toString() { result = "UnmodeledDefinition" } }

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,11 @@ module InstructionSanity {
2929
tag instanceof RightOperandTag
3030
)
3131
) or
32-
opcode instanceof CopyOpcode and tag instanceof CopySourceOperandTag or
3332
opcode instanceof MemoryAccessOpcode and tag instanceof AddressOperandTag or
3433
opcode instanceof BufferAccessOpcode and tag instanceof BufferSizeOperand or
3534
opcode instanceof OpcodeWithCondition and tag instanceof ConditionOperandTag or
36-
opcode instanceof Opcode::ReturnValue and tag instanceof ReturnValueOperandTag or
37-
opcode instanceof Opcode::ThrowValue and tag instanceof ExceptionOperandTag or
35+
opcode instanceof OpcodeWithLoad and tag instanceof LoadOperandTag or
36+
opcode instanceof Opcode::Store and tag instanceof StoreValueOperandTag or
3837
opcode instanceof Opcode::UnmodeledUse and tag instanceof UnmodeledUseOperandTag or
3938
opcode instanceof Opcode::Call and tag instanceof CallTargetOperandTag or
4039
opcode instanceof Opcode::Chi and tag instanceof ChiTotalOperandTag or
@@ -714,7 +713,7 @@ class ReturnValueInstruction extends ReturnInstruction {
714713
getOpcode() instanceof Opcode::ReturnValue
715714
}
716715

717-
final ReturnValueOperand getReturnValueOperand() {
716+
final LoadOperand getReturnValueOperand() {
718717
result = getAnOperand()
719718
}
720719

@@ -728,19 +727,23 @@ class CopyInstruction extends Instruction {
728727
getOpcode() instanceof CopyOpcode
729728
}
730729

731-
final CopySourceOperand getSourceValueOperand() {
732-
result = getAnOperand()
730+
Operand getSourceValueOperand() {
731+
none()
733732
}
734-
733+
735734
final Instruction getSourceValue() {
736735
result = getSourceValueOperand().getDefinitionInstruction()
737736
}
738737
}
739738

740-
class CopyValueInstruction extends CopyInstruction {
739+
class CopyValueInstruction extends CopyInstruction, UnaryInstruction {
741740
CopyValueInstruction() {
742741
getOpcode() instanceof Opcode::CopyValue
743742
}
743+
744+
override final UnaryOperand getSourceValueOperand() {
745+
result = getAnOperand()
746+
}
744747
}
745748

746749
class LoadInstruction extends CopyInstruction {
@@ -755,6 +758,10 @@ class LoadInstruction extends CopyInstruction {
755758
final Instruction getSourceAddress() {
756759
result = getSourceAddressOperand().getDefinitionInstruction()
757760
}
761+
762+
override final LoadOperand getSourceValueOperand() {
763+
result = getAnOperand()
764+
}
758765
}
759766

760767
class StoreInstruction extends CopyInstruction {
@@ -773,6 +780,10 @@ class StoreInstruction extends CopyInstruction {
773780
final Instruction getDestinationAddress() {
774781
result = getDestinationAddressOperand().getDefinitionInstruction()
775782
}
783+
784+
override final StoreValueOperand getSourceValueOperand() {
785+
result = getAnOperand()
786+
}
776787
}
777788

778789
class ConditionalBranchInstruction extends Instruction {
@@ -1442,7 +1453,7 @@ class ThrowValueInstruction extends ThrowInstruction {
14421453
/**
14431454
* Gets the operand for the exception thrown by this instruction.
14441455
*/
1445-
final ExceptionOperand getExceptionOperand() {
1456+
final LoadOperand getExceptionOperand() {
14461457
result = getAnOperand()
14471458
}
14481459

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll

Lines changed: 56 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,21 @@ class Operand extends TOperand {
6363
int getDumpSortOrder() {
6464
result = -1
6565
}
66+
}
67+
68+
/**
69+
* An operand that consumes a memory result (e.g. the `LoadOperand` on a `Load` instruction).
70+
*/
71+
class MemoryOperand extends Operand {
72+
MemoryOperand() {
73+
exists(MemoryOperandTag tag |
74+
this = TNonPhiOperand(_, tag, _)
75+
) or
76+
this = TPhiOperand(_, _, _)
77+
}
6678

6779
/**
68-
* Gets the kind of memory access performed by the operand. Holds only for memory operands.
80+
* Gets the kind of memory access performed by the operand.
6981
*/
7082
MemoryAccessKind getMemoryAccess() {
7183
none()
@@ -82,6 +94,17 @@ class Operand extends TOperand {
8294
}
8395
}
8496

97+
/**
98+
* An operand that consumes a register (non-memory) result.
99+
*/
100+
class RegisterOperand extends Operand {
101+
RegisterOperand() {
102+
exists(RegisterOperandTag tag |
103+
this = TNonPhiOperand(_, tag, _)
104+
)
105+
}
106+
}
107+
85108
/**
86109
* An operand that is not an operand of a `PhiInstruction`.
87110
*/
@@ -119,7 +142,7 @@ class NonPhiOperand extends Operand, TNonPhiOperand {
119142
* The address operand of an instruction that loads or stores a value from
120143
* memory (e.g. `Load`, `Store`).
121144
*/
122-
class AddressOperand extends NonPhiOperand {
145+
class AddressOperand extends NonPhiOperand, RegisterOperand {
123146
AddressOperand() {
124147
this = TNonPhiOperand(_, addressOperand(), _)
125148
}
@@ -130,28 +153,40 @@ class AddressOperand extends NonPhiOperand {
130153
}
131154

132155
/**
133-
* The source value operand of an instruction that copies this value to its
134-
* result (e.g. `Copy`, `Load`, `Store`).
156+
* The source value operand of an instruction that loads a value from memory (e.g. `Load`,
157+
* `ReturnValue`, `ThrowValue`).
135158
*/
136-
class CopySourceOperand extends NonPhiOperand {
137-
CopySourceOperand() {
138-
this = TNonPhiOperand(_, copySourceOperand(), _)
159+
class LoadOperand extends NonPhiOperand, MemoryOperand {
160+
LoadOperand() {
161+
this = TNonPhiOperand(_, loadOperand(), _)
139162
}
140163

141164
override string toString() {
142-
result = "CopySource"
165+
result = "Load"
143166
}
144167

145168
override final MemoryAccessKind getMemoryAccess() {
146-
instr.getOpcode() instanceof Opcode::Load and
147169
result instanceof IndirectMemoryAccess
148170
}
149171
}
150172

151173
/**
152-
* The sole operand of a unary instruction (e.g. `Convert`, `Negate`).
174+
* The source value operand of a `Store` instruction.
153175
*/
154-
class UnaryOperand extends NonPhiOperand {
176+
class StoreValueOperand extends NonPhiOperand, RegisterOperand {
177+
StoreValueOperand() {
178+
this = TNonPhiOperand(_, storeValueOperand(), _)
179+
}
180+
181+
override string toString() {
182+
result = "StoreValue"
183+
}
184+
}
185+
186+
/**
187+
* The sole operand of a unary instruction (e.g. `Convert`, `Negate`, `Copy`).
188+
*/
189+
class UnaryOperand extends NonPhiOperand, RegisterOperand {
155190
UnaryOperand() {
156191
this = TNonPhiOperand(_, unaryOperand(), _)
157192
}
@@ -164,7 +199,7 @@ class UnaryOperand extends NonPhiOperand {
164199
/**
165200
* The left operand of a binary instruction (e.g. `Add`, `CompareEQ`).
166201
*/
167-
class LeftOperand extends NonPhiOperand {
202+
class LeftOperand extends NonPhiOperand, RegisterOperand {
168203
LeftOperand() {
169204
this = TNonPhiOperand(_, leftOperand(), _)
170205
}
@@ -177,7 +212,7 @@ class LeftOperand extends NonPhiOperand {
177212
/**
178213
* The right operand of a binary instruction (e.g. `Add`, `CompareEQ`).
179214
*/
180-
class RightOperand extends NonPhiOperand {
215+
class RightOperand extends NonPhiOperand, RegisterOperand {
181216
RightOperand() {
182217
this = TNonPhiOperand(_, rightOperand(), _)
183218
}
@@ -187,44 +222,10 @@ class RightOperand extends NonPhiOperand {
187222
}
188223
}
189224

190-
/**
191-
* The return value operand of a `ReturnValue` instruction.
192-
*/
193-
class ReturnValueOperand extends NonPhiOperand {
194-
ReturnValueOperand() {
195-
this = TNonPhiOperand(_, returnValueOperand(), _)
196-
}
197-
198-
override string toString() {
199-
result = "ReturnValue"
200-
}
201-
202-
override final MemoryAccessKind getMemoryAccess() {
203-
result instanceof IndirectMemoryAccess
204-
}
205-
}
206-
207-
/**
208-
* The exception thrown by a `ThrowValue` instruction.
209-
*/
210-
class ExceptionOperand extends NonPhiOperand {
211-
ExceptionOperand() {
212-
this = TNonPhiOperand(_, exceptionOperand(), _)
213-
}
214-
215-
override string toString() {
216-
result = "Exception"
217-
}
218-
219-
override final MemoryAccessKind getMemoryAccess() {
220-
result instanceof IndirectMemoryAccess
221-
}
222-
}
223-
224225
/**
225226
* The condition operand of a `ConditionalBranch` or `Switch` instruction.
226227
*/
227-
class ConditionOperand extends NonPhiOperand {
228+
class ConditionOperand extends NonPhiOperand, RegisterOperand {
228229
ConditionOperand() {
229230
this = TNonPhiOperand(_, conditionOperand(), _)
230231
}
@@ -238,7 +239,7 @@ class ConditionOperand extends NonPhiOperand {
238239
* An operand of the special `UnmodeledUse` instruction, representing a value
239240
* whose set of uses is unknown.
240241
*/
241-
class UnmodeledUseOperand extends NonPhiOperand {
242+
class UnmodeledUseOperand extends NonPhiOperand, MemoryOperand {
242243
UnmodeledUseOperand() {
243244
this = TNonPhiOperand(_, unmodeledUseOperand(), _)
244245
}
@@ -255,7 +256,7 @@ class UnmodeledUseOperand extends NonPhiOperand {
255256
/**
256257
* The operand representing the target function of an `Call` instruction.
257258
*/
258-
class CallTargetOperand extends NonPhiOperand {
259+
class CallTargetOperand extends NonPhiOperand, RegisterOperand {
259260
CallTargetOperand() {
260261
this = TNonPhiOperand(_, callTargetOperand(), _)
261262
}
@@ -270,7 +271,7 @@ class CallTargetOperand extends NonPhiOperand {
270271
* positional arguments (represented by `PositionalArgumentOperand`) and the
271272
* implicit `this` argument, if any (represented by `ThisArgumentOperand`).
272273
*/
273-
class ArgumentOperand extends NonPhiOperand {
274+
class ArgumentOperand extends NonPhiOperand, RegisterOperand {
274275
ArgumentOperand() {
275276
exists(ArgumentOperandTag argTag |
276277
this = TNonPhiOperand(_, argTag, _)
@@ -317,7 +318,7 @@ class PositionalArgumentOperand extends ArgumentOperand {
317318
}
318319
}
319320

320-
class SideEffectOperand extends NonPhiOperand {
321+
class SideEffectOperand extends NonPhiOperand, MemoryOperand {
321322
SideEffectOperand() {
322323
this = TNonPhiOperand(_, sideEffectOperand(), _)
323324
}
@@ -352,7 +353,7 @@ class SideEffectOperand extends NonPhiOperand {
352353
/**
353354
* An operand of a `PhiInstruction`.
354355
*/
355-
class PhiOperand extends Operand, TPhiOperand {
356+
class PhiOperand extends MemoryOperand, TPhiOperand {
356357
PhiInstruction useInstr;
357358
Instruction defInstr;
358359
IRBlock predecessorBlock;
@@ -393,19 +394,10 @@ class PhiOperand extends Operand, TPhiOperand {
393394
}
394395
}
395396

396-
/**
397-
* An operand that reads a value from memory.
398-
*/
399-
class MemoryOperand extends Operand {
400-
MemoryOperand() {
401-
exists(getMemoryAccess())
402-
}
403-
}
404-
405397
/**
406398
* The total operand of a Chi node, representing the previous value of the memory.
407399
*/
408-
class ChiTotalOperand extends Operand {
400+
class ChiTotalOperand extends MemoryOperand {
409401
ChiTotalOperand() {
410402
this = TNonPhiOperand(_, chiTotalOperand(), _)
411403
}
@@ -423,7 +415,7 @@ class ChiTotalOperand extends Operand {
423415
/**
424416
* The partial operand of a Chi node, representing the value being written to part of the memory.
425417
*/
426-
class ChiPartialOperand extends Operand {
418+
class ChiPartialOperand extends MemoryOperand {
427419
ChiPartialOperand() {
428420
this = TNonPhiOperand(_, chiPartialOperand(), _)
429421
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ predicate operandIsPropagated(Operand operand, IntValue bitOffset) {
134134
// offset of the field.
135135
bitOffset = getFieldBitOffset(instr.(FieldAddressInstruction).getField()) or
136136
// A copy propagates the source value.
137-
operand instanceof CopySourceOperand and bitOffset = 0
137+
operand = instr.(CopyInstruction).getSourceValueOperand() and bitOffset = 0
138138
)
139139
)
140140
}

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,8 +263,7 @@ MemoryAccess getResultMemoryAccess(Instruction instr) {
263263
)
264264
}
265265

266-
MemoryAccess getOperandMemoryAccess(Operand operand) {
267-
exists(operand.getMemoryAccess()) and
266+
MemoryAccess getOperandMemoryAccess(MemoryOperand operand) {
268267
if exists(IRVariable var, IntValue i |
269268
resultPointsTo(operand.getAddressOperand().getDefinitionInstruction(), var, i)
270269
)

0 commit comments

Comments
 (0)