Skip to content

Commit c73b516

Browse files
Merge pull request #1541 from jbj/ir-operand-exact
C++ IR: Make instruction operand getters have only exact results
2 parents 00ff2bb + 2324ce7 commit c73b516

File tree

26 files changed

+371
-241
lines changed

26 files changed

+371
-241
lines changed

cpp/ql/src/semmle/code/cpp/ir/dataflow/TaintTracking.qll

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ module TaintTracking {
136136
// Taint can flow through expressions that alter the value but preserve
137137
// more than one bit of it _or_ expressions that follow data through
138138
// pointer indirections.
139-
nodeTo.getAnOperand().getDefinitionInstruction() = nodeFrom and
139+
nodeTo.getAnOperand().getAnyDef() = nodeFrom and
140140
(
141141
nodeTo instanceof ArithmeticInstruction
142142
or
@@ -145,6 +145,11 @@ module TaintTracking {
145145
nodeTo instanceof PointerArithmeticInstruction
146146
or
147147
nodeTo instanceof FieldAddressInstruction
148+
or
149+
// The `CopyInstruction` case is also present in non-taint data flow, but
150+
// that uses `getDef` rather than `getAnyDef`. For taint, we want flow
151+
// from a definition of `myStruct` to a `myStruct.myField` expression.
152+
nodeTo instanceof CopyInstruction
148153
)
149154
or
150155
nodeTo.(LoadInstruction).getSourceAddress() = nodeFrom

cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ UninitializedNode uninitializedNode(LocalVariable v) { result.getLocalVariable()
143143
*/
144144
predicate localFlowStep(Node nodeFrom, Node nodeTo) {
145145
nodeTo.(CopyInstruction).getSourceValue() = nodeFrom or
146-
nodeTo.(PhiInstruction).getAnOperand().getDefinitionInstruction() = nodeFrom or
146+
nodeTo.(PhiInstruction).getAnOperand().getDef() = nodeFrom or
147147
// Treat all conversions as flow, even conversions between different numeric types.
148148
nodeTo.(ConvertInstruction).getUnary() = nodeFrom
149149
}

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

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ module InstructionSanity {
103103
query predicate missingOperandType(Operand operand, string message) {
104104
exists(Function func |
105105
not exists(operand.getType()) and
106-
func = operand.getUseInstruction().getEnclosingFunction() and
106+
func = operand.getUse().getEnclosingFunction() and
107107
message = "Operand missing type in function '" + getIdentityString(func) + "'."
108108
)
109109
}
@@ -158,8 +158,8 @@ module InstructionSanity {
158158
* a different function.
159159
*/
160160
query predicate operandAcrossFunctions(Operand operand, Instruction instr, Instruction defInstr) {
161-
operand.getUseInstruction() = instr and
162-
operand.getDefinitionInstruction() = defInstr and
161+
operand.getUse() = instr and
162+
operand.getAnyDef() = defInstr and
163163
instr.getEnclosingIRFunction() != defInstr.getEnclosingIRFunction()
164164
}
165165

@@ -480,17 +480,18 @@ class Instruction extends Construction::TInstruction {
480480
}
481481

482482
/**
483-
* Gets all direct uses of the result of this instruction.
483+
* Gets all direct uses of the result of this instruction. The result can be
484+
* an `Operand` for which `isDefinitionInexact` holds.
484485
*/
485486
final Operand getAUse() {
486-
result.getDefinitionInstruction() = this
487+
result.getAnyDef() = this
487488
}
488489

489490
/**
490491
* Gets all of this instruction's operands.
491492
*/
492493
final Operand getAnOperand() {
493-
result.getUseInstruction() = this
494+
result.getUse() = this
494495
}
495496

496497
/**
@@ -509,13 +510,22 @@ class Instruction extends Construction::TInstruction {
509510
}
510511

511512
/**
512-
* Returns the operand that holds the memory address to which the instruction stores its
513+
* Gets the operand that holds the memory address to which this instruction stores its
513514
* result, if any. For example, in `m3 = Store r1, r2`, the result of `getResultAddressOperand()`
514515
* is `r1`.
515516
*/
516517
final AddressOperand getResultAddressOperand() {
517518
getResultMemoryAccess().usesAddressOperand() and
518-
result.getUseInstruction() = this
519+
result.getUse() = this
520+
}
521+
522+
/**
523+
* Gets the instruction that holds the exact memory address to which this instruction stores its
524+
* result, if any. For example, in `m3 = Store r1, r2`, the result of `getResultAddressOperand()`
525+
* is the instruction that defines `r1`.
526+
*/
527+
final Instruction getResultAddress() {
528+
result = getResultAddressOperand().getDef()
519529
}
520530

521531
/**
@@ -698,7 +708,7 @@ class FieldAddressInstruction extends FieldInstruction {
698708
}
699709

700710
final Instruction getObjectAddress() {
701-
result = getObjectAddressOperand().getDefinitionInstruction()
711+
result = getObjectAddressOperand().getDef()
702712
}
703713
}
704714

@@ -763,7 +773,7 @@ class ReturnValueInstruction extends ReturnInstruction {
763773
}
764774

765775
final Instruction getReturnValue() {
766-
result = getReturnValueOperand().getDefinitionInstruction()
776+
result = getReturnValueOperand().getDef()
767777
}
768778
}
769779

@@ -777,7 +787,7 @@ class CopyInstruction extends Instruction {
777787
}
778788

779789
final Instruction getSourceValue() {
780-
result = getSourceValueOperand().getDefinitionInstruction()
790+
result = getSourceValueOperand().getDef()
781791
}
782792
}
783793

@@ -801,7 +811,7 @@ class LoadInstruction extends CopyInstruction {
801811
}
802812

803813
final Instruction getSourceAddress() {
804-
result = getSourceAddressOperand().getDefinitionInstruction()
814+
result = getSourceAddressOperand().getDef()
805815
}
806816

807817
override final LoadOperand getSourceValueOperand() {
@@ -823,7 +833,7 @@ class StoreInstruction extends CopyInstruction {
823833
}
824834

825835
final Instruction getDestinationAddress() {
826-
result = getDestinationAddressOperand().getDefinitionInstruction()
836+
result = getDestinationAddressOperand().getDef()
827837
}
828838

829839
override final StoreValueOperand getSourceValueOperand() {
@@ -841,7 +851,7 @@ class ConditionalBranchInstruction extends Instruction {
841851
}
842852

843853
final Instruction getCondition() {
844-
result = getConditionOperand().getDefinitionInstruction()
854+
result = getConditionOperand().getDef()
845855
}
846856

847857
final Instruction getTrueSuccessor() {
@@ -907,11 +917,11 @@ class BinaryInstruction extends Instruction {
907917
}
908918

909919
final Instruction getLeft() {
910-
result = getLeftOperand().getDefinitionInstruction()
920+
result = getLeftOperand().getDef()
911921
}
912922

913923
final Instruction getRight() {
914-
result = getRightOperand().getDefinitionInstruction()
924+
result = getRightOperand().getDef()
915925
}
916926

917927
/**
@@ -1061,7 +1071,7 @@ class UnaryInstruction extends Instruction {
10611071
}
10621072

10631073
final Instruction getUnary() {
1064-
result = getUnaryOperand().getDefinitionInstruction()
1074+
result = getUnaryOperand().getDef()
10651075
}
10661076
}
10671077

@@ -1291,7 +1301,7 @@ class SwitchInstruction extends Instruction {
12911301
}
12921302

12931303
final Instruction getExpression() {
1294-
result = getExpressionOperand().getDefinitionInstruction()
1304+
result = getExpressionOperand().getDef()
12951305
}
12961306

12971307
final Instruction getACaseSuccessor() {
@@ -1326,7 +1336,7 @@ class CallInstruction extends Instruction {
13261336
* function pointer.
13271337
*/
13281338
final Instruction getCallTarget() {
1329-
result = getCallTargetOperand().getDefinitionInstruction()
1339+
result = getCallTargetOperand().getDef()
13301340
}
13311341

13321342
/**
@@ -1347,7 +1357,7 @@ class CallInstruction extends Instruction {
13471357
* Gets all of the arguments of the call, including the `this` pointer, if any.
13481358
*/
13491359
final Instruction getAnArgument() {
1350-
result = getAnArgumentOperand().getDefinitionInstruction()
1360+
result = getAnArgumentOperand().getDef()
13511361
}
13521362

13531363
/**
@@ -1361,7 +1371,7 @@ class CallInstruction extends Instruction {
13611371
* Gets the `this` pointer argument of the call, if any.
13621372
*/
13631373
final Instruction getThisArgument() {
1364-
result = getThisArgumentOperand().getDefinitionInstruction()
1374+
result = getThisArgumentOperand().getDef()
13651375
}
13661376

13671377
/**
@@ -1376,7 +1386,7 @@ class CallInstruction extends Instruction {
13761386
* Gets the argument at the specified index.
13771387
*/
13781388
final Instruction getPositionalArgument(int index) {
1379-
result = getPositionalArgumentOperand(index).getDefinitionInstruction()
1389+
result = getPositionalArgumentOperand(index).getDef()
13801390
}
13811391
}
13821392

@@ -1532,7 +1542,7 @@ class ThrowValueInstruction extends ThrowInstruction {
15321542
* Gets the address of the exception thrown by this instruction.
15331543
*/
15341544
final Instruction getExceptionAddress() {
1535-
result = getExceptionAddressOperand().getDefinitionInstruction()
1545+
result = getExceptionAddressOperand().getDef()
15361546
}
15371547

15381548
/**
@@ -1546,7 +1556,7 @@ class ThrowValueInstruction extends ThrowInstruction {
15461556
* Gets the exception thrown by this instruction.
15471557
*/
15481558
final Instruction getException() {
1549-
result = getExceptionOperand().getDefinitionInstruction()
1559+
result = getExceptionOperand().getDef()
15501560
}
15511561
}
15521562

@@ -1676,7 +1686,7 @@ class PhiInstruction extends Instruction {
16761686
*/
16771687
pragma[noinline]
16781688
final Instruction getAnInput() {
1679-
result = this.getAnInputOperand().getDefinitionInstruction()
1689+
result = this.getAnInputOperand().getDef()
16801690
}
16811691
}
16821692

@@ -1744,7 +1754,7 @@ class ChiInstruction extends Instruction {
17441754
* memory write.
17451755
*/
17461756
final Instruction getTotal() {
1747-
result = getTotalOperand().getDefinitionInstruction()
1757+
result = getTotalOperand().getDef()
17481758
}
17491759

17501760
/**
@@ -1758,7 +1768,7 @@ class ChiInstruction extends Instruction {
17581768
* Gets the operand that represents the new value written by the memory write.
17591769
*/
17601770
final Instruction getPartial() {
1761-
result = getPartialOperand().getDefinitionInstruction()
1771+
result = getPartialOperand().getDef()
17621772
}
17631773
}
17641774

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

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,27 +27,63 @@ class Operand extends TOperand {
2727
}
2828

2929
final Location getLocation() {
30-
result = getUseInstruction().getLocation()
30+
result = getUse().getLocation()
3131
}
3232

3333
final IRFunction getEnclosingIRFunction() {
34-
result = getUseInstruction().getEnclosingIRFunction()
34+
result = getUse().getEnclosingIRFunction()
3535
}
36-
36+
3737
/**
3838
* Gets the `Instruction` that consumes this operand.
3939
*/
40-
Instruction getUseInstruction() {
40+
Instruction getUse() {
4141
none()
4242
}
4343

4444
/**
45-
* Gets the `Instruction` whose result is the value of the operand.
45+
* Gets the `Instruction` whose result is the value of the operand. Unlike
46+
* `getDef`, this also has a result when `isDefinitionInexact` holds, which
47+
* means that the resulting instruction may only _partially_ or _potentially_
48+
* be the value of this operand.
4649
*/
47-
Instruction getDefinitionInstruction() {
50+
Instruction getAnyDef() {
4851
none()
4952
}
5053

54+
/**
55+
* Gets the `Instruction` whose result is the value of the operand. Unlike
56+
* `getAnyDef`, this also has no result when `isDefinitionInexact` holds,
57+
* which means that the resulting instruction must always be exactly the be
58+
* the value of this operand.
59+
*/
60+
final Instruction getDef() {
61+
result = this.getAnyDef() and
62+
getDefinitionOverlap() instanceof MustExactlyOverlap
63+
}
64+
65+
/**
66+
* DEPRECATED: renamed to `getUse`.
67+
*
68+
* Gets the `Instruction` that consumes this operand.
69+
*/
70+
deprecated
71+
final Instruction getUseInstruction() {
72+
result = getUse()
73+
}
74+
75+
/**
76+
* DEPRECATED: use `getAnyDef` or `getDef`. The exact replacement for this
77+
* predicate is `getAnyDef`, but most uses of this predicate should probably
78+
* be replaced with `getDef`.
79+
*
80+
* Gets the `Instruction` whose result is the value of the operand.
81+
*/
82+
deprecated
83+
final Instruction getDefinitionInstruction() {
84+
result = getAnyDef()
85+
}
86+
5187
/**
5288
* Gets the overlap relationship between the operand's definition and its use.
5389
*/
@@ -77,7 +113,7 @@ class Operand extends TOperand {
77113
* For example: `this:r3_5`
78114
*/
79115
final string getDumpString() {
80-
result = getDumpLabel() + getInexactSpecifier() + getDefinitionInstruction().getResultId()
116+
result = getDumpLabel() + getInexactSpecifier() + getAnyDef().getResultId()
81117
}
82118

83119
/**
@@ -107,7 +143,7 @@ class Operand extends TOperand {
107143
* has been cast to a different type.
108144
*/
109145
Type getType() {
110-
result = getDefinitionInstruction().getResultType()
146+
result = getAnyDef().getResultType()
111147
}
112148

113149
/**
@@ -118,7 +154,7 @@ class Operand extends TOperand {
118154
* given by `getResultType()`.
119155
*/
120156
predicate isGLValue() {
121-
getDefinitionInstruction().isGLValue()
157+
getAnyDef().isGLValue()
122158
}
123159

124160
/**
@@ -158,7 +194,7 @@ class MemoryOperand extends Operand {
158194
*/
159195
final AddressOperand getAddressOperand() {
160196
getMemoryAccess().usesAddressOperand() and
161-
result.getUseInstruction() = getUseInstruction()
197+
result.getUse() = getUse()
162198
}
163199
}
164200

@@ -175,11 +211,11 @@ class NonPhiOperand extends Operand {
175211
this = TNonPhiMemoryOperand(useInstr, tag, defInstr, _)
176212
}
177213

178-
override final Instruction getUseInstruction() {
214+
override final Instruction getUse() {
179215
result = useInstr
180216
}
181217

182-
override final Instruction getDefinitionInstruction() {
218+
override final Instruction getAnyDef() {
183219
result = defInstr
184220
}
185221

@@ -437,11 +473,11 @@ class PhiInputOperand extends MemoryOperand, TPhiOperand {
437473
result = "Phi"
438474
}
439475

440-
override final PhiInstruction getUseInstruction() {
476+
override final PhiInstruction getUse() {
441477
result = useInstr
442478
}
443479

444-
override final Instruction getDefinitionInstruction() {
480+
override final Instruction getAnyDef() {
445481
result = defInstr
446482
}
447483

0 commit comments

Comments
 (0)