C++: Merge 'PostUpdateFieldNode' and 'IndirectArgumentOutNode' into a single IPA branch.

This commit is contained in:
Mathias Vorreiter Pedersen
2023-12-07 19:49:17 +00:00
parent c1cc441da7
commit d6871c7cf9

View File

@@ -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() }
} }
/** /**