mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
C++: Add more QLDoc to StoreNode and LoadNode classes, and related predicates. I also simplified the code a bit by moving common implementations of predicates into shared super classes. Finally, I added a getLocation predicate to StoreNode to match the structure of the LoadNode class.
This commit is contained in:
@@ -462,20 +462,46 @@ private newtype TStoreChain =
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A `StoreChain` represents a series of field lookups that compute the destination of a store.
|
||||
* For example, given an assignment such as `a.b.c = x`, there are two `StoreChain`s:
|
||||
* One corresponding to the field `b`, and one corresponding to the field `c`. Here, `b` is the parent
|
||||
* `StoreChain` of `c`.
|
||||
*/
|
||||
private class StoreChain extends TStoreChain {
|
||||
string toString() { none() }
|
||||
|
||||
StoreChainConsCons getParent() { none() }
|
||||
/**
|
||||
* Gets the parent of this `StoreChain`, if any. For example, for the assignment
|
||||
* ```
|
||||
* a.b.c = x;
|
||||
* ```
|
||||
* the parent of `c` is `b`, and `b` has no parent.
|
||||
*/
|
||||
final StoreChainConsCons getParent() { result.getChild() = this }
|
||||
|
||||
/** Gets the child of this `StoreChain`, if any. */
|
||||
StoreChain getChild() { none() }
|
||||
|
||||
/**
|
||||
* Gets the instruction that receives flow from the outermost `StoreChain` of this chain (i.e.,
|
||||
* the `StoreChain` with no parent).
|
||||
*/
|
||||
StoreChainEndInstruction getEndInstruction() { none() }
|
||||
|
||||
/**
|
||||
* Gets the instruction that flows to the innermost `StoreChain` of this chain (i.e.,
|
||||
* the `StoreChain` with no child).
|
||||
*/
|
||||
Instruction getBeginInstruction() { none() }
|
||||
|
||||
/** Gets the `FieldAddressInstruction` of this `StoreChain` */
|
||||
FieldAddressInstruction getFieldInstruction() { none() }
|
||||
|
||||
/** Gets the `FieldAddressInstruction` of any `StoreChain` in this chain. */
|
||||
FieldAddressInstruction getAFieldInstruction() { none() }
|
||||
|
||||
final Location getLocation() { result = getFieldInstruction().getLocation() }
|
||||
}
|
||||
|
||||
private class StoreChainConsNil extends StoreChain, TStoreChainConsNil {
|
||||
@@ -486,8 +512,6 @@ private class StoreChainConsNil extends StoreChain, TStoreChainConsNil {
|
||||
|
||||
override string toString() { result = fi.getField().toString() }
|
||||
|
||||
override StoreChainConsCons getParent() { result = TStoreChainConsCons(_, this) }
|
||||
|
||||
override StoreChainEndInstruction getEndInstruction() { result = end }
|
||||
|
||||
override Instruction getBeginInstruction() { result = end.getBeginInstruction() }
|
||||
@@ -505,8 +529,6 @@ private class StoreChainConsCons extends StoreChain, TStoreChainConsCons {
|
||||
|
||||
override string toString() { result = fi.getField().toString() + "." + next.toString() }
|
||||
|
||||
override StoreChainConsCons getParent() { result.getChild() = this }
|
||||
|
||||
override StoreChain getChild() { result = next }
|
||||
|
||||
override FieldAddressInstruction getFieldInstruction() { result = fi }
|
||||
@@ -563,18 +585,34 @@ private class LoadChainEndInstructionLoad extends LoadChainEndInstruction, LoadI
|
||||
override Instruction getReadValue() { result = getSourceValueOperand().getAnyDef() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A `LoadChain` represents a series of field lookups that compute the source address of a load.
|
||||
* For example, given the field lookup in `f(a.b.c)`, there are two `LoadChains`s:
|
||||
* One corresponding to the field `b`, and one corresponding to the field `c`. Here, `b` is the parent
|
||||
* `LoadChain` of `c`.
|
||||
*/
|
||||
private class LoadChain extends TLoadChain {
|
||||
string toString() { none() }
|
||||
|
||||
/**
|
||||
* Gets the instruction that receives flow from the innermost `LoadChain` of this chain (i.e.,
|
||||
* the `LoadChain` with no child).
|
||||
*/
|
||||
LoadChainEndInstruction getEndInstruction() { none() }
|
||||
|
||||
/**
|
||||
* Gets the parent of this `LoadChain`, if any. For example in `f(a.b.c)` the parent of `c` is `b`,
|
||||
* and `b` has no parent.
|
||||
*/
|
||||
final LoadChainConsCons getParent() { result.getChild() = this }
|
||||
|
||||
/** Gets the child of this `LoadChain`, if any. */
|
||||
LoadChain getChild() { none() }
|
||||
|
||||
/** Gets the `FieldAddressInstruction` of this `LoadChain` */
|
||||
FieldAddressInstruction getFieldInstruction() { none() }
|
||||
|
||||
Location getLocation() { none() }
|
||||
final Location getLocation() { result = getFieldInstruction().getLocation() }
|
||||
}
|
||||
|
||||
private class LoadChainConsNil extends LoadChain, TLoadChainConsNil {
|
||||
@@ -588,8 +626,6 @@ private class LoadChainConsNil extends LoadChain, TLoadChainConsNil {
|
||||
override LoadChainEndInstruction getEndInstruction() { result = end }
|
||||
|
||||
override FieldAddressInstruction getFieldInstruction() { result = fi }
|
||||
|
||||
override Location getLocation() { result = fi.getLocation() }
|
||||
}
|
||||
|
||||
private class LoadChainConsCons extends LoadChain, TLoadChainConsCons {
|
||||
@@ -605,11 +641,21 @@ private class LoadChainConsCons extends LoadChain, TLoadChainConsCons {
|
||||
override LoadChain getChild() { result = next }
|
||||
|
||||
override FieldAddressInstruction getFieldInstruction() { result = fi }
|
||||
|
||||
override Location getLocation() { result = fi.getLocation() }
|
||||
}
|
||||
|
||||
/** `StoreNode` also extends `ReadStepNode` to participate in reverse read steps. */
|
||||
/**
|
||||
* A dataflow node generated by a partial definition.
|
||||
* The `StoreNode` class extends `ReadStepNode` to participate in reverse read steps.
|
||||
* A reverse read is a store step that is "inferred" by the DataFlow library. For example in the
|
||||
* assignment:
|
||||
* ```
|
||||
* a.b.c = x;
|
||||
* ```
|
||||
* Here, the access path after the store must reflect that a value has been stored into the field `c` of
|
||||
* the object at field `b`. The field `c` is added to the access path through a `storeStep`, and the
|
||||
* field `b` is inferred by the DataFlow library because there's a read step (reading the field `b`) from
|
||||
* the pre update node for `b.c` to the pre update node for `c`.
|
||||
*/
|
||||
private class StoreNode extends TStoreNode, StoreStepNode, ReadStepNode, PartialDefinitionNode {
|
||||
StoreChain storeChain;
|
||||
|
||||
@@ -649,6 +695,7 @@ private class StoreNode extends TStoreNode, StoreStepNode, ReadStepNode, Partial
|
||||
}
|
||||
}
|
||||
|
||||
/** A dataflow node generated by loading from an address computed by a sequence of fields lookups. */
|
||||
private class LoadNode extends TLoadNode, ReadStepNode {
|
||||
LoadChain loadChain;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user