mirror of
https://github.com/github/codeql.git
synced 2025-12-20 18:56:32 +01:00
C++: Merge 'PostUpdateFieldNode' and 'IndirectArgumentOutNode' into a single IPA branch.
This commit is contained in:
@@ -18,17 +18,17 @@ private import codeql.util.Unit
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The IR dataflow graph consists of the following nodes:
|
* The IR dataflow graph consists of the following nodes:
|
||||||
* - `Node0`, which injects most instructions and operands directly into the dataflow graph.
|
* - `Node0`, which injects most instructions and operands directly into the
|
||||||
|
* dataflow graph.
|
||||||
* - `VariableNode`, which is used to model flow through global variables.
|
* - `VariableNode`, which is used to model flow through global variables.
|
||||||
* - `PostFieldUpdateNode`, which is used to model the state of a field after a value has been stored
|
* - `PostUpdateNodeImpl`, which is used to model the state of an object after
|
||||||
* into an address after a number of loads.
|
* an update after a number of loads.
|
||||||
* - `SsaPhiNode`, which represents phi nodes as computed by the shared SSA library.
|
* - `SsaPhiNode`, which represents phi nodes as computed by the shared SSA
|
||||||
* - `IndirectArgumentOutNode`, which represents the value of an argument (and its indirections) after
|
* library.
|
||||||
* it leaves a function call.
|
* - `RawIndirectOperand`, which represents the value of `operand` after
|
||||||
* - `RawIndirectOperand`, which represents the value of `operand` after loading the address a number
|
* loading the address a number of times.
|
||||||
* of times.
|
* - `RawIndirectInstruction`, which represents the value of `instr` after
|
||||||
* - `RawIndirectInstruction`, which represents the value of `instr` after loading the address a number
|
* loading the address a number of times.
|
||||||
* of times.
|
|
||||||
*/
|
*/
|
||||||
cached
|
cached
|
||||||
private newtype TIRDataFlowNode =
|
private newtype TIRDataFlowNode =
|
||||||
@@ -37,14 +37,13 @@ private newtype TIRDataFlowNode =
|
|||||||
indirectionIndex =
|
indirectionIndex =
|
||||||
[getMinIndirectionsForType(var.getUnspecifiedType()) .. Ssa::getMaxIndirectionsForType(var.getUnspecifiedType())]
|
[getMinIndirectionsForType(var.getUnspecifiedType()) .. Ssa::getMaxIndirectionsForType(var.getUnspecifiedType())]
|
||||||
} or
|
} or
|
||||||
TPostFieldUpdateNode(FieldAddress operand, int indirectionIndex) {
|
TPostUpdateNodeImpl(Operand operand, int indirectionIndex) {
|
||||||
indirectionIndex =
|
operand = any(FieldAddress fa).getObjectAddressOperand() and
|
||||||
[1 .. Ssa::countIndirectionsForCppType(operand.getObjectAddress().getResultLanguageType())]
|
indirectionIndex = [1 .. Ssa::countIndirectionsForCppType(Ssa::getLanguageType(operand))]
|
||||||
} or
|
or
|
||||||
TSsaPhiNode(Ssa::PhiNode phi) or
|
|
||||||
TIndirectArgumentOutNode(ArgumentOperand operand, int indirectionIndex) {
|
|
||||||
Ssa::isModifiableByCall(operand, indirectionIndex)
|
Ssa::isModifiableByCall(operand, indirectionIndex)
|
||||||
} or
|
} or
|
||||||
|
TSsaPhiNode(Ssa::PhiNode phi) or
|
||||||
TRawIndirectOperand0(Node0Impl node, int indirectionIndex) {
|
TRawIndirectOperand0(Node0Impl node, int indirectionIndex) {
|
||||||
Ssa::hasRawIndirectOperand(node.asOperand(), indirectionIndex)
|
Ssa::hasRawIndirectOperand(node.asOperand(), indirectionIndex)
|
||||||
} or
|
} or
|
||||||
@@ -84,7 +83,7 @@ private predicate parameterIsRedefined(Parameter p) {
|
|||||||
class FieldAddress extends Operand {
|
class FieldAddress extends Operand {
|
||||||
FieldAddressInstruction fai;
|
FieldAddressInstruction fai;
|
||||||
|
|
||||||
FieldAddress() { fai = this.getDef() }
|
FieldAddress() { fai = this.getDef() and not Ssa::ignoreOperand(this) }
|
||||||
|
|
||||||
/** Gets the field associated with this instruction. */
|
/** Gets the field associated with this instruction. */
|
||||||
Field getField() { result = fai.getField() }
|
Field getField() { result = fai.getField() }
|
||||||
@@ -550,37 +549,44 @@ Type stripPointer(Type t) {
|
|||||||
result = t.(FunctionPointerIshType).getBaseType()
|
result = t.(FunctionPointerIshType).getBaseType()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class PostUpdateNodeImpl extends PartialDefinitionNode, TPostUpdateNodeImpl {
|
||||||
|
int indirectionIndex;
|
||||||
|
Operand operand;
|
||||||
|
|
||||||
|
PostUpdateNodeImpl() { this = TPostUpdateNodeImpl(operand, indirectionIndex) }
|
||||||
|
|
||||||
|
override Declaration getFunction() { result = operand.getUse().getEnclosingFunction() }
|
||||||
|
|
||||||
|
override Declaration getEnclosingCallable() { result = this.getFunction() }
|
||||||
|
|
||||||
|
/** Gets the operand associated with this node. */
|
||||||
|
Operand getOperand() { result = operand }
|
||||||
|
|
||||||
|
/** Gets the indirection index associated with this node. */
|
||||||
|
int getIndirectionIndex() { result = indirectionIndex }
|
||||||
|
|
||||||
|
override Location getLocationImpl() { result = operand.getLocation() }
|
||||||
|
|
||||||
|
final override Node getPreUpdateNode() { hasOperandAndIndex(result, operand, indirectionIndex) }
|
||||||
|
|
||||||
|
final override Expr getDefinedExpr() {
|
||||||
|
result = operand.getDef().getUnconvertedResultExpression()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* INTERNAL: do not use.
|
* INTERNAL: do not use.
|
||||||
*
|
*
|
||||||
* The node representing the value of a field after it has been updated.
|
* The node representing the value of a field after it has been updated.
|
||||||
*/
|
*/
|
||||||
class PostFieldUpdateNode extends TPostFieldUpdateNode, PartialDefinitionNode {
|
class PostFieldUpdateNode extends PostUpdateNodeImpl {
|
||||||
int indirectionIndex;
|
|
||||||
FieldAddress fieldAddress;
|
FieldAddress fieldAddress;
|
||||||
|
|
||||||
PostFieldUpdateNode() { this = TPostFieldUpdateNode(fieldAddress, indirectionIndex) }
|
PostFieldUpdateNode() { operand = fieldAddress.getObjectAddressOperand() }
|
||||||
|
|
||||||
override Declaration getFunction() { result = fieldAddress.getUse().getEnclosingFunction() }
|
|
||||||
|
|
||||||
override Declaration getEnclosingCallable() { result = this.getFunction() }
|
|
||||||
|
|
||||||
FieldAddress getFieldAddress() { result = fieldAddress }
|
FieldAddress getFieldAddress() { result = fieldAddress }
|
||||||
|
|
||||||
Field getUpdatedField() { result = fieldAddress.getField() }
|
Field getUpdatedField() { result = this.getFieldAddress().getField() }
|
||||||
|
|
||||||
int getIndirectionIndex() { result = indirectionIndex }
|
|
||||||
|
|
||||||
override Node getPreUpdateNode() {
|
|
||||||
hasOperandAndIndex(result, pragma[only_bind_into](fieldAddress).getObjectAddressOperand(),
|
|
||||||
indirectionIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
override Expr getDefinedExpr() {
|
|
||||||
result = fieldAddress.getObjectAddress().getUnconvertedResultExpression()
|
|
||||||
}
|
|
||||||
|
|
||||||
override Location getLocationImpl() { result = fieldAddress.getLocation() }
|
|
||||||
|
|
||||||
override string toStringImpl() { result = this.getPreUpdateNode() + " [post update]" }
|
override string toStringImpl() { result = this.getPreUpdateNode() + " [post update]" }
|
||||||
}
|
}
|
||||||
@@ -816,13 +822,8 @@ class IndirectReturnNode extends Node {
|
|||||||
* A node representing the indirection of a value after it
|
* A node representing the indirection of a value after it
|
||||||
* has been returned from a function.
|
* has been returned from a function.
|
||||||
*/
|
*/
|
||||||
class IndirectArgumentOutNode extends Node, TIndirectArgumentOutNode, PartialDefinitionNode {
|
class IndirectArgumentOutNode extends PostUpdateNodeImpl {
|
||||||
ArgumentOperand operand;
|
override ArgumentOperand operand;
|
||||||
int indirectionIndex;
|
|
||||||
|
|
||||||
IndirectArgumentOutNode() { this = TIndirectArgumentOutNode(operand, indirectionIndex) }
|
|
||||||
|
|
||||||
int getIndirectionIndex() { result = indirectionIndex }
|
|
||||||
|
|
||||||
int getArgumentIndex() {
|
int getArgumentIndex() {
|
||||||
exists(CallInstruction call | call.getArgumentOperand(result) = operand)
|
exists(CallInstruction call | call.getArgumentOperand(result) = operand)
|
||||||
@@ -834,12 +835,6 @@ class IndirectArgumentOutNode extends Node, TIndirectArgumentOutNode, PartialDef
|
|||||||
|
|
||||||
Function getStaticCallTarget() { result = this.getCallInstruction().getStaticCallTarget() }
|
Function getStaticCallTarget() { result = this.getCallInstruction().getStaticCallTarget() }
|
||||||
|
|
||||||
override Declaration getEnclosingCallable() { result = this.getFunction() }
|
|
||||||
|
|
||||||
override Declaration getFunction() { result = this.getCallInstruction().getEnclosingFunction() }
|
|
||||||
|
|
||||||
override Node getPreUpdateNode() { hasOperandAndIndex(result, operand, indirectionIndex) }
|
|
||||||
|
|
||||||
override string toStringImpl() {
|
override string toStringImpl() {
|
||||||
// This string should be unique enough to be helpful but common enough to
|
// This string should be unique enough to be helpful but common enough to
|
||||||
// avoid storing too many different strings.
|
// avoid storing too many different strings.
|
||||||
@@ -848,10 +843,6 @@ class IndirectArgumentOutNode extends Node, TIndirectArgumentOutNode, PartialDef
|
|||||||
not exists(this.getStaticCallTarget()) and
|
not exists(this.getStaticCallTarget()) and
|
||||||
result = "output argument"
|
result = "output argument"
|
||||||
}
|
}
|
||||||
|
|
||||||
override Location getLocationImpl() { result = operand.getLocation() }
|
|
||||||
|
|
||||||
override Expr getDefinedExpr() { result = operand.getDef().getUnconvertedResultExpression() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user