Skip to content

Commit 9b361f1

Browse files
author
Robert Marsh
authored
Merge pull request #2601 from dbartol/dbartol/OpcodeProperties
C++: Consolidate opcode properties onto `Opcode` class
2 parents cf5dd85 + 690d23d commit 9b361f1

File tree

18 files changed

+505
-813
lines changed

18 files changed

+505
-813
lines changed

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

Lines changed: 228 additions & 38 deletions
Large diffs are not rendered by default.

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

Lines changed: 6 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -11,60 +11,12 @@ import Imports::Opcode
1111
private import Imports::OperandTag
1212

1313
module InstructionSanity {
14-
/**
15-
* Holds if the instruction `instr` should be expected to have an operand
16-
* with operand tag `tag`. Only holds for singleton operand tags. Tags with
17-
* parameters, such as `PhiInputOperand` and `PositionalArgumentOperand` are handled
18-
* separately in `unexpectedOperand`.
19-
*/
20-
private predicate expectsOperand(Instruction instr, OperandTag tag) {
21-
exists(Opcode opcode |
22-
opcode = instr.getOpcode() and
23-
(
24-
opcode instanceof UnaryOpcode and tag instanceof UnaryOperandTag
25-
or
26-
opcode instanceof BinaryOpcode and
27-
(
28-
tag instanceof LeftOperandTag or
29-
tag instanceof RightOperandTag
30-
)
31-
or
32-
opcode instanceof MemoryAccessOpcode and tag instanceof AddressOperandTag
33-
or
34-
opcode instanceof SizedBufferAccessOpcode and tag instanceof BufferSizeOperandTag
35-
or
36-
opcode instanceof OpcodeWithCondition and tag instanceof ConditionOperandTag
37-
or
38-
opcode instanceof OpcodeWithLoad and tag instanceof LoadOperandTag
39-
or
40-
opcode instanceof Opcode::Store and tag instanceof StoreValueOperandTag
41-
or
42-
opcode instanceof Opcode::UnmodeledUse and tag instanceof UnmodeledUseOperandTag
43-
or
44-
opcode instanceof Opcode::Call and tag instanceof CallTargetOperandTag
45-
or
46-
opcode instanceof Opcode::Chi and tag instanceof ChiTotalOperandTag
47-
or
48-
opcode instanceof Opcode::Chi and tag instanceof ChiPartialOperandTag
49-
or
50-
(
51-
opcode instanceof ReadSideEffectOpcode or
52-
opcode instanceof Opcode::InlineAsm or
53-
opcode instanceof Opcode::CallSideEffect or
54-
opcode instanceof Opcode::ReturnIndirection or
55-
opcode instanceof Opcode::AliasedUse
56-
) and
57-
tag instanceof SideEffectOperandTag
58-
)
59-
)
60-
}
61-
6214
/**
6315
* Holds if instruction `instr` is missing an expected operand with tag `tag`.
6416
*/
6517
query predicate missingOperand(Instruction instr, string message, IRFunction func, string funcText) {
6618
exists(OperandTag tag |
67-
expectsOperand(instr, tag) and
19+
instr.getOpcode().hasOperand(tag) and
6820
not exists(NonPhiOperand operand |
6921
operand = instr.getAnOperand() and
7022
operand.getOperandTag() = tag
@@ -84,7 +36,7 @@ module InstructionSanity {
8436
operand = instr.getAnOperand() and
8537
operand.getOperandTag() = tag
8638
) and
87-
not expectsOperand(instr, tag) and
39+
not instr.getOpcode().hasOperand(tag) and
8840
not (instr instanceof CallInstruction and tag instanceof ArgumentOperandTag) and
8941
not (
9042
instr instanceof BuiltInOperationInstruction and tag instanceof PositionalArgumentOperandTag
@@ -549,7 +501,8 @@ class Instruction extends Construction::TInstruction {
549501
* Gets the kind of memory access performed by this instruction's result.
550502
* Holds only for instructions with a memory result.
551503
*/
552-
MemoryAccessKind getResultMemoryAccess() { none() }
504+
pragma[inline]
505+
final MemoryAccessKind getResultMemoryAccess() { result = getOpcode().getWriteMemoryAccess() }
553506

554507
/**
555508
* Holds if the memory access performed by this instruction's result will not always write to
@@ -559,7 +512,8 @@ class Instruction extends Construction::TInstruction {
559512
* location is a conservative estimate of the memory that might actually be accessed at runtime
560513
* (for example, the global side effects of a function call).
561514
*/
562-
predicate hasResultMayMemoryAccess() { none() }
515+
pragma[inline]
516+
final predicate hasResultMayMemoryAccess() { getOpcode().hasMayWriteMemoryAccess() }
563517

564518
/**
565519
* Gets the operand that holds the memory address to which this instruction stores its
@@ -710,16 +664,12 @@ class InitializeParameterInstruction extends VariableInstruction {
710664
InitializeParameterInstruction() { getOpcode() instanceof Opcode::InitializeParameter }
711665

712666
final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() }
713-
714-
final override MemoryAccessKind getResultMemoryAccess() { result instanceof IndirectMemoryAccess }
715667
}
716668

717669
class InitializeIndirectionInstruction extends VariableInstruction {
718670
InitializeIndirectionInstruction() { getOpcode() instanceof Opcode::InitializeIndirection }
719671

720672
final Language::Parameter getParameter() { result = var.(IRUserVariable).getVariable() }
721-
722-
final override MemoryAccessKind getResultMemoryAccess() { result instanceof IndirectMemoryAccess }
723673
}
724674

725675
/**
@@ -754,8 +704,6 @@ class ErrorInstruction extends Instruction {
754704
class UninitializedInstruction extends VariableInstruction {
755705
UninitializedInstruction() { getOpcode() instanceof Opcode::Uninitialized }
756706

757-
final override MemoryAccessKind getResultMemoryAccess() { result instanceof IndirectMemoryAccess }
758-
759707
/**
760708
* Gets the variable that is uninitialized.
761709
*/
@@ -821,8 +769,6 @@ class LoadInstruction extends CopyInstruction {
821769
class StoreInstruction extends CopyInstruction {
822770
StoreInstruction() { getOpcode() instanceof Opcode::Store }
823771

824-
final override MemoryAccessKind getResultMemoryAccess() { result instanceof IndirectMemoryAccess }
825-
826772
final AddressOperand getDestinationAddressOperand() { result = getAnOperand() }
827773

828774
final Instruction getDestinationAddress() { result = getDestinationAddressOperand().getDef() }
@@ -1236,10 +1182,6 @@ class SideEffectInstruction extends Instruction {
12361182
*/
12371183
class CallSideEffectInstruction extends SideEffectInstruction {
12381184
CallSideEffectInstruction() { getOpcode() instanceof Opcode::CallSideEffect }
1239-
1240-
final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess }
1241-
1242-
final override predicate hasResultMayMemoryAccess() { any() }
12431185
}
12441186

12451187
/**
@@ -1303,8 +1245,6 @@ class IndirectMustWriteSideEffectInstruction extends WriteSideEffectInstruction
13031245
IndirectMustWriteSideEffectInstruction() {
13041246
getOpcode() instanceof Opcode::IndirectMustWriteSideEffect
13051247
}
1306-
1307-
final override MemoryAccessKind getResultMemoryAccess() { result instanceof IndirectMemoryAccess }
13081248
}
13091249

13101250
/**
@@ -1315,8 +1255,6 @@ class BufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
13151255
BufferMustWriteSideEffectInstruction() {
13161256
getOpcode() instanceof Opcode::BufferMustWriteSideEffect
13171257
}
1318-
1319-
final override MemoryAccessKind getResultMemoryAccess() { result instanceof BufferMemoryAccess }
13201258
}
13211259

13221260
/**
@@ -1328,8 +1266,6 @@ class SizedBufferMustWriteSideEffectInstruction extends WriteSideEffectInstructi
13281266
getOpcode() instanceof Opcode::SizedBufferMustWriteSideEffect
13291267
}
13301268

1331-
final override MemoryAccessKind getResultMemoryAccess() { result instanceof BufferMemoryAccess }
1332-
13331269
Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() }
13341270
}
13351271

@@ -1342,10 +1278,6 @@ class IndirectMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
13421278
IndirectMayWriteSideEffectInstruction() {
13431279
getOpcode() instanceof Opcode::IndirectMayWriteSideEffect
13441280
}
1345-
1346-
final override MemoryAccessKind getResultMemoryAccess() { result instanceof IndirectMemoryAccess }
1347-
1348-
final override predicate hasResultMayMemoryAccess() { any() }
13491281
}
13501282

13511283
/**
@@ -1354,10 +1286,6 @@ class IndirectMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
13541286
*/
13551287
class BufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
13561288
BufferMayWriteSideEffectInstruction() { getOpcode() instanceof Opcode::BufferMayWriteSideEffect }
1357-
1358-
final override MemoryAccessKind getResultMemoryAccess() { result instanceof BufferMemoryAccess }
1359-
1360-
final override predicate hasResultMayMemoryAccess() { any() }
13611289
}
13621290

13631291
/**
@@ -1369,10 +1297,6 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio
13691297
getOpcode() instanceof Opcode::SizedBufferMayWriteSideEffect
13701298
}
13711299

1372-
final override MemoryAccessKind getResultMemoryAccess() { result instanceof BufferMemoryAccess }
1373-
1374-
final override predicate hasResultMayMemoryAccess() { any() }
1375-
13761300
Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() }
13771301
}
13781302

@@ -1381,10 +1305,6 @@ class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstructio
13811305
*/
13821306
class InlineAsmInstruction extends Instruction {
13831307
InlineAsmInstruction() { getOpcode() instanceof Opcode::InlineAsm }
1384-
1385-
final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess }
1386-
1387-
final override predicate hasResultMayMemoryAccess() { any() }
13881308
}
13891309

13901310
/**
@@ -1470,19 +1390,13 @@ class CatchAnyInstruction extends CatchInstruction {
14701390

14711391
class UnmodeledDefinitionInstruction extends Instruction {
14721392
UnmodeledDefinitionInstruction() { getOpcode() instanceof Opcode::UnmodeledDefinition }
1473-
1474-
final override MemoryAccessKind getResultMemoryAccess() {
1475-
result instanceof UnmodeledMemoryAccess
1476-
}
14771393
}
14781394

14791395
/**
14801396
* An instruction that initializes all escaped memory.
14811397
*/
14821398
class AliasedDefinitionInstruction extends Instruction {
14831399
AliasedDefinitionInstruction() { getOpcode() instanceof Opcode::AliasedDefinition }
1484-
1485-
final override MemoryAccessKind getResultMemoryAccess() { result instanceof EscapedMemoryAccess }
14861400
}
14871401

14881402
/**
@@ -1511,8 +1425,6 @@ class UnmodeledUseInstruction extends Instruction {
15111425
class PhiInstruction extends Instruction {
15121426
PhiInstruction() { getOpcode() instanceof Opcode::Phi }
15131427

1514-
final override MemoryAccessKind getResultMemoryAccess() { result instanceof PhiMemoryAccess }
1515-
15161428
/**
15171429
* Gets all of the instruction's `PhiInputOperand`s, representing the values that flow from each predecessor block.
15181430
*/
@@ -1573,8 +1485,6 @@ class PhiInstruction extends Instruction {
15731485
class ChiInstruction extends Instruction {
15741486
ChiInstruction() { getOpcode() instanceof Opcode::Chi }
15751487

1576-
final override MemoryAccessKind getResultMemoryAccess() { result instanceof ChiTotalMemoryAccess }
1577-
15781488
/**
15791489
* Gets the operand that represents the previous state of all memory that might be aliased by the
15801490
* memory write.

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

Lines changed: 2 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ class MemoryOperand extends Operand {
170170
/**
171171
* Gets the kind of memory access performed by the operand.
172172
*/
173-
MemoryAccessKind getMemoryAccess() { none() }
173+
MemoryAccessKind getMemoryAccess() { result = getUse().getOpcode().getReadMemoryAccess() }
174174

175175
/**
176176
* Holds if the memory access performed by this operand will not always read from every bit in the
@@ -180,7 +180,7 @@ class MemoryOperand extends Operand {
180180
* conservative estimate of the memory that might actually be accessed at runtime (for example,
181181
* the global side effects of a function call).
182182
*/
183-
predicate hasMayMemoryAccess() { none() }
183+
predicate hasMayReadMemoryAccess() { getUse().getOpcode().hasMayReadMemoryAccess() }
184184

185185
/**
186186
* Returns the operand that holds the memory address from which the current operand loads its
@@ -274,8 +274,6 @@ class LoadOperand extends TypedOperand {
274274
override LoadOperandTag tag;
275275

276276
override string toString() { result = "Load" }
277-
278-
final override MemoryAccessKind getMemoryAccess() { result instanceof IndirectMemoryAccess }
279277
}
280278

281279
/**
@@ -331,8 +329,6 @@ class UnmodeledUseOperand extends NonPhiMemoryOperand {
331329
override UnmodeledUseOperandTag tag;
332330

333331
override string toString() { result = "UnmodeledUse" }
334-
335-
final override MemoryAccessKind getMemoryAccess() { result instanceof UnmodeledMemoryAccess }
336332
}
337333

338334
/**
@@ -382,50 +378,6 @@ class PositionalArgumentOperand extends ArgumentOperand {
382378

383379
class SideEffectOperand extends TypedOperand {
384380
override SideEffectOperandTag tag;
385-
386-
override MemoryAccessKind getMemoryAccess() {
387-
useInstr instanceof AliasedUseInstruction and
388-
result instanceof NonLocalMemoryAccess
389-
or
390-
useInstr instanceof CallSideEffectInstruction and
391-
result instanceof EscapedMemoryAccess
392-
or
393-
useInstr instanceof CallReadSideEffectInstruction and
394-
result instanceof EscapedMemoryAccess
395-
or
396-
useInstr instanceof IndirectReadSideEffectInstruction and
397-
result instanceof IndirectMemoryAccess
398-
or
399-
useInstr instanceof BufferReadSideEffectInstruction and
400-
result instanceof BufferMemoryAccess
401-
or
402-
useInstr instanceof IndirectMustWriteSideEffectInstruction and
403-
result instanceof IndirectMemoryAccess
404-
or
405-
useInstr instanceof BufferMustWriteSideEffectInstruction and
406-
result instanceof BufferMemoryAccess
407-
or
408-
useInstr instanceof IndirectMayWriteSideEffectInstruction and
409-
result instanceof IndirectMemoryAccess
410-
or
411-
useInstr instanceof BufferMayWriteSideEffectInstruction and
412-
result instanceof BufferMemoryAccess
413-
or
414-
useInstr instanceof ReturnIndirectionInstruction and
415-
result instanceof BufferMemoryAccess
416-
}
417-
418-
final override predicate hasMayMemoryAccess() {
419-
useInstr instanceof AliasedUseInstruction
420-
or
421-
useInstr instanceof CallSideEffectInstruction
422-
or
423-
useInstr instanceof CallReadSideEffectInstruction
424-
or
425-
useInstr instanceof IndirectMayWriteSideEffectInstruction
426-
or
427-
useInstr instanceof BufferMayWriteSideEffectInstruction
428-
}
429381
}
430382

431383
/**

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ private predicate hasOperandMemoryAccess(
2929
resultPointsTo(operand.getAddressOperand().getAnyDef(), var, startBitOffset) and
3030
languageType = operand.getLanguageType() and
3131
type = languageType.getIRType() and
32-
(if operand.hasMayMemoryAccess() then isMayAccess = true else isMayAccess = false) and
32+
(if operand.hasMayReadMemoryAccess() then isMayAccess = true else isMayAccess = false) and
3333
if exists(type.getByteSize())
3434
then endBitOffset = Ints::add(startBitOffset, Ints::mul(type.getByteSize(), 8))
3535
else endBitOffset = Ints::unknown()
@@ -483,7 +483,7 @@ MemoryLocation getResultMemoryLocation(Instruction instr) {
483483
MemoryLocation getOperandMemoryLocation(MemoryOperand operand) {
484484
exists(MemoryAccessKind kind, boolean isMayAccess |
485485
kind = operand.getMemoryAccess() and
486-
(if operand.hasMayMemoryAccess() then isMayAccess = true else isMayAccess = false) and
486+
(if operand.hasMayReadMemoryAccess() then isMayAccess = true else isMayAccess = false) and
487487
(
488488
(
489489
kind.usesAddressOperand() and
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import semmle.code.cpp.ir.implementation.MemoryAccessKind as MemoryAccessKind

0 commit comments

Comments
 (0)