C++: Add DefinitionByReferenceNode to IR dataflow

This commit is contained in:
Robert Marsh
2019-11-04 16:16:18 -08:00
parent fa8e5e6793
commit 39b400ca69
6 changed files with 77 additions and 5 deletions

View File

@@ -173,11 +173,53 @@ abstract class PostUpdateNode extends Node {
abstract Node getPreUpdateNode();
}
/**
* A node that represents the value of a variable after a function call that
* may have changed the variable because it's passed by reference.
*
* A typical example would be a call `f(&x)`. Firstly, there will be flow into
* `x` from previous definitions of `x`. Secondly, there will be a
* `DefinitionByReferenceNode` to represent the value of `x` after the call has
* returned. This node will have its `getArgument()` equal to `&x` and its
* `getVariableAccess()` equal to `x`.
*/
class DefinitionByReferenceNode extends Node {
override WriteSideEffectInstruction instr;
/** Gets the argument corresponding to this node. */
Expr getArgument() {
result = instr
.getPrimaryInstruction()
.(CallInstruction)
.getPositionalArgument(instr.getIndex())
.getUnconvertedResultExpression()
or
result = instr
.getPrimaryInstruction()
.(CallInstruction)
.getThisArgument()
.getUnconvertedResultExpression() and
instr.getIndex() = -1
}
/** Gets the parameter through which this value is assigned. */
Parameter getParameter() {
exists(CallInstruction ci |
result = ci.getStaticCallTarget().getParameter(instr.getIndex())
)
}
}
/**
* Gets the node corresponding to `instr`.
*/
Node instructionNode(Instruction instr) { result.asInstruction() = instr }
DefinitionByReferenceNode definitionByReferenceNode(Expr e) {
result.getArgument() = e
}
/**
* Gets a `Node` corresponding to `e` or any of its conversions. There is no
* result if `e` is a `Conversion`.

View File

@@ -1236,6 +1236,8 @@ class IndirectReadSideEffectInstruction extends SideEffectInstruction {
IndirectReadSideEffectInstruction() { getOpcode() instanceof Opcode::IndirectReadSideEffect }
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
Instruction getSideEffect() { result = getAnOperand().(SideEffectOperand).getDef() }
}
/**
@@ -1245,6 +1247,8 @@ class BufferReadSideEffectInstruction extends SideEffectInstruction {
BufferReadSideEffectInstruction() { getOpcode() instanceof Opcode::BufferReadSideEffect }
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
Instruction getSideEffect() { result = getAnOperand().(SideEffectOperand).getDef() }
}
/**
@@ -1258,12 +1262,14 @@ class SizedBufferReadSideEffectInstruction extends SideEffectInstruction {
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() }
Instruction getSideEffect() { result = getAnOperand().(SideEffectOperand).getDef() }
}
/**
* An instruction representing a side effect of a function call.
*/
class WriteSideEffectInstruction extends SideEffectInstruction {
class WriteSideEffectInstruction extends SideEffectInstruction, IndexedInstruction {
WriteSideEffectInstruction() { getOpcode() instanceof WriteSideEffectOpcode }
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }

View File

@@ -1236,6 +1236,8 @@ class IndirectReadSideEffectInstruction extends SideEffectInstruction {
IndirectReadSideEffectInstruction() { getOpcode() instanceof Opcode::IndirectReadSideEffect }
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
Instruction getSideEffect() { result = getAnOperand().(SideEffectOperand).getDef() }
}
/**
@@ -1245,6 +1247,8 @@ class BufferReadSideEffectInstruction extends SideEffectInstruction {
BufferReadSideEffectInstruction() { getOpcode() instanceof Opcode::BufferReadSideEffect }
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
Instruction getSideEffect() { result = getAnOperand().(SideEffectOperand).getDef() }
}
/**
@@ -1258,12 +1262,14 @@ class SizedBufferReadSideEffectInstruction extends SideEffectInstruction {
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() }
Instruction getSideEffect() { result = getAnOperand().(SideEffectOperand).getDef() }
}
/**
* An instruction representing a side effect of a function call.
*/
class WriteSideEffectInstruction extends SideEffectInstruction {
class WriteSideEffectInstruction extends SideEffectInstruction, IndexedInstruction {
WriteSideEffectInstruction() { getOpcode() instanceof WriteSideEffectOpcode }
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }

View File

@@ -1236,6 +1236,8 @@ class IndirectReadSideEffectInstruction extends SideEffectInstruction {
IndirectReadSideEffectInstruction() { getOpcode() instanceof Opcode::IndirectReadSideEffect }
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
Instruction getSideEffect() { result = getAnOperand().(SideEffectOperand).getDef() }
}
/**
@@ -1245,6 +1247,8 @@ class BufferReadSideEffectInstruction extends SideEffectInstruction {
BufferReadSideEffectInstruction() { getOpcode() instanceof Opcode::BufferReadSideEffect }
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
Instruction getSideEffect() { result = getAnOperand().(SideEffectOperand).getDef() }
}
/**
@@ -1258,12 +1262,14 @@ class SizedBufferReadSideEffectInstruction extends SideEffectInstruction {
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() }
Instruction getSideEffect() { result = getAnOperand().(SideEffectOperand).getDef() }
}
/**
* An instruction representing a side effect of a function call.
*/
class WriteSideEffectInstruction extends SideEffectInstruction {
class WriteSideEffectInstruction extends SideEffectInstruction, IndexedInstruction {
WriteSideEffectInstruction() { getOpcode() instanceof WriteSideEffectOpcode }
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }