Skip to content

Commit 258d041

Browse files
committed
C++: Replace SkippableInstruction with local flow steps.
1 parent 6545d0b commit 258d041

File tree

3 files changed

+28
-70
lines changed

3 files changed

+28
-70
lines changed

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

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -346,24 +346,6 @@ private class ArrayToPointerConvertInstruction extends ConvertInstruction {
346346
}
347347
}
348348

349-
/**
350-
* These two predicates look like copy-paste from the two predicates with the same name in DataFlowUtil,
351-
* but crucially they only skip past `CopyValueInstruction`s. This is because we use a special case of
352-
* a `ConvertInstruction` to detect some read steps from arrays that undergoes array-to-pointer
353-
* conversion.
354-
*/
355-
private Instruction skipOneCopyValueInstructionRec(CopyValueInstruction copy) {
356-
copy.getUnary() = result and not result instanceof CopyValueInstruction
357-
or
358-
result = skipOneCopyValueInstructionRec(copy.getUnary())
359-
}
360-
361-
private Instruction skipCopyValueInstructions(Operand op) {
362-
not result instanceof CopyValueInstruction and result = op.getDef()
363-
or
364-
result = skipOneCopyValueInstructionRec(op.getDef())
365-
}
366-
367349
private class InexactLoadOperand extends LoadOperand {
368350
InexactLoadOperand() { this.isDefinitionInexact() }
369351
}
@@ -375,7 +357,8 @@ private predicate arrayReadStep(Node node1, ArrayContent a, Node node2) {
375357
node1.asInstruction() = operand.getAnyDef() and
376358
not node1.asInstruction().isResultConflated() and
377359
operand = node2.asOperand() and
378-
address = skipCopyValueInstructions(operand.getAddressOperand()) and
360+
instructionOperandLocalFlowStep+(instructionNode(address),
361+
operandNode(operand.getAddressOperand())) and
379362
(
380363
address instanceof LoadInstruction or
381364
address instanceof ArrayToPointerConvertInstruction or

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

Lines changed: 23 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -185,54 +185,15 @@ class OperandNode extends Node, TOperandNode {
185185
override string toString() { result = this.getOperand().toString() }
186186
}
187187

188-
/** An abstract class that defines conversion-like instructions. */
189-
abstract private class SkippableInstruction extends Instruction {
190-
abstract Instruction getSourceInstruction();
191-
}
192-
193-
/**
194-
* Gets the instruction that is propaged through a non-empty sequence of conversion-like instructions.
195-
*/
196-
private Instruction skipSkippableInstructionsRec(SkippableInstruction skip) {
197-
result = skip.getSourceInstruction() and not result instanceof SkippableInstruction
198-
or
199-
result = skipSkippableInstructionsRec(skip.getSourceInstruction())
200-
}
201-
202-
/**
203-
* Gets the instruction that is propagated through a (possibly empty) sequence of conversion-like
204-
* instructions.
205-
*/
206-
private Instruction skipSkippableInstructions(Instruction instr) {
207-
result = instr and not result instanceof SkippableInstruction
208-
or
209-
result = skipSkippableInstructionsRec(instr)
210-
}
211-
212-
private class SkippableCopyValueInstruction extends SkippableInstruction, CopyValueInstruction {
213-
override Instruction getSourceInstruction() { result = this.getSourceValue() }
214-
}
215-
216-
private class SkippableConvertInstruction extends SkippableInstruction, ConvertInstruction {
217-
override Instruction getSourceInstruction() { result = this.getUnary() }
218-
}
219-
220-
private class SkippableCheckedConvertInstruction extends SkippableInstruction,
221-
CheckedConvertOrNullInstruction {
222-
override Instruction getSourceInstruction() { result = this.getUnary() }
223-
}
224-
225-
private class SkippableInheritanceConversionInstruction extends SkippableInstruction,
226-
InheritanceConversionInstruction {
227-
override Instruction getSourceInstruction() { result = this.getUnary() }
228-
}
229-
230188
/**
231189
* INTERNAL: do not use. Gets the `FieldNode` corresponding to `instr`, if
232190
* `instr` is an instruction that propagates an address of a `FieldAddressInstruction`.
233191
*/
234192
FieldNode getFieldNodeForFieldInstruction(Instruction instr) {
235-
result.getFieldInstruction() = skipSkippableInstructions(instr)
193+
result.getFieldInstruction() =
194+
any(FieldAddressInstruction fai |
195+
instructionOperandLocalFlowStep*(instructionNode(fai), instructionNode(instr))
196+
)
236197
}
237198

238199
/**
@@ -651,6 +612,11 @@ class VariableNode extends Node, TVariableNode {
651612
*/
652613
InstructionNode instructionNode(Instruction instr) { result.getInstruction() = instr }
653614

615+
/**
616+
* Gets the node corresponding to `operand`.
617+
*/
618+
OperandNode operandNode(Operand operand) { result.getOperand() = operand }
619+
654620
/**
655621
* DEPRECATED: use `definitionByReferenceNodeFromArgument` instead.
656622
*
@@ -770,17 +736,26 @@ private predicate flowIntoReadNode(Node nodeFrom, FieldNode nodeTo) {
770736

771737
/**
772738
* INTERNAL: do not use.
773-
*
774-
* This is the local flow predicate that's used as a building block in global
775-
* data flow. It may have less flow than the `localFlowStep` predicate.
739+
* Holds if `nodeFrom` is an operand and `nodeTo` is an instruction node that uses this operand, or
740+
* if `nodeFrom` is an instruction and `nodeTo` is an operand that refers to this instruction.
776741
*/
777-
cached
778-
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
742+
predicate instructionOperandLocalFlowStep(Node nodeFrom, Node nodeTo) {
779743
// Operand -> Instruction flow
780744
simpleInstructionLocalFlowStep(nodeFrom.asOperand(), nodeTo.asInstruction())
781745
or
782746
// Instruction -> Operand flow
783747
simpleOperandLocalFlowStep(nodeFrom.asInstruction(), nodeTo.asOperand())
748+
}
749+
750+
/**
751+
* INTERNAL: do not use.
752+
*
753+
* This is the local flow predicate that's used as a building block in global
754+
* data flow. It may have less flow than the `localFlowStep` predicate.
755+
*/
756+
cached
757+
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
758+
instructionOperandLocalFlowStep(nodeFrom, nodeTo)
784759
or
785760
flowIntoReadNode(nodeFrom, nodeTo)
786761
or

cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ edges
5858
| aliasing.cpp:79:11:79:20 | call to user_input | aliasing.cpp:80:12:80:13 | m1 |
5959
| aliasing.cpp:86:10:86:19 | call to user_input | aliasing.cpp:87:12:87:13 | m1 |
6060
| aliasing.cpp:92:12:92:21 | call to user_input | aliasing.cpp:93:12:93:13 | m1 |
61-
| aliasing.cpp:98:5:98:6 | m1 [post update] [m1] | aliasing.cpp:100:14:100:14 | Store [m1] |
61+
| aliasing.cpp:98:5:98:6 | m1 [post update] [m1] | aliasing.cpp:101:21:101:22 | m1 [m1] |
6262
| aliasing.cpp:98:10:98:19 | call to user_input | aliasing.cpp:98:5:98:6 | m1 [post update] [m1] |
63-
| aliasing.cpp:100:14:100:14 | Store [m1] | aliasing.cpp:102:8:102:10 | * ... |
63+
| aliasing.cpp:101:21:101:22 | m1 [m1] | aliasing.cpp:102:8:102:10 | * ... |
6464
| aliasing.cpp:106:3:106:20 | Chi [array content] | aliasing.cpp:121:15:121:16 | taint_a_ptr output argument [array content] |
6565
| aliasing.cpp:106:3:106:20 | Chi [array content] | aliasing.cpp:126:15:126:20 | taint_a_ptr output argument [array content] |
6666
| aliasing.cpp:106:3:106:20 | Chi [array content] | aliasing.cpp:131:15:131:16 | taint_a_ptr output argument [array content] |
@@ -373,7 +373,7 @@ nodes
373373
| aliasing.cpp:93:12:93:13 | m1 | semmle.label | m1 |
374374
| aliasing.cpp:98:5:98:6 | m1 [post update] [m1] | semmle.label | m1 [post update] [m1] |
375375
| aliasing.cpp:98:10:98:19 | call to user_input | semmle.label | call to user_input |
376-
| aliasing.cpp:100:14:100:14 | Store [m1] | semmle.label | Store [m1] |
376+
| aliasing.cpp:101:21:101:22 | m1 [m1] | semmle.label | m1 [m1] |
377377
| aliasing.cpp:102:8:102:10 | * ... | semmle.label | * ... |
378378
| aliasing.cpp:106:3:106:20 | Chi [array content] | semmle.label | Chi [array content] |
379379
| aliasing.cpp:106:3:106:20 | ChiTotal [post update] [array content] | semmle.label | ChiTotal [post update] [array content] |

0 commit comments

Comments
 (0)