mirror of
https://github.com/github/codeql.git
synced 2026-04-28 18:25:24 +02:00
C#: Add new class AssignableDefinitionNode to the data-flow library
This commit is contained in:
@@ -554,15 +554,10 @@ class SsaDefinitionNode extends Node, TSsaDefinitionNode {
|
||||
|
||||
private module ParameterNodes {
|
||||
/**
|
||||
* Holds if SSA definition node `node` is an entry definition for parameter `p`.
|
||||
* Holds if definition node `node` is an entry definition for parameter `p`.
|
||||
*/
|
||||
predicate explicitParameterNode(SsaDefinitionNode node, Parameter p) {
|
||||
exists(Ssa::ExplicitDefinition def, AssignableDefinitions::ImplicitParameterDefinition pdef |
|
||||
node = TSsaDefinitionNode(def)
|
||||
|
|
||||
pdef = def.getADefinition() and
|
||||
p = pdef.getParameter()
|
||||
)
|
||||
predicate explicitParameterNode(AssignableDefinitionNode node, Parameter p) {
|
||||
p = node.getDefinition().(AssignableDefinitions::ImplicitParameterDefinition).getParameter()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1126,13 +1121,14 @@ private module OutNodes {
|
||||
* A data flow node that reads a value returned by a callable using an
|
||||
* `out` or `ref` parameter.
|
||||
*/
|
||||
class ParamOutNode extends OutNode, SsaDefinitionNode {
|
||||
class ParamOutNode extends OutNode, AssignableDefinitionNode {
|
||||
private AssignableDefinitions::OutRefDefinition outRefDef;
|
||||
private ControlFlow::Node cfn;
|
||||
|
||||
ParamOutNode() { outRefDef = this.getDefinition().(Ssa::ExplicitDefinition).getADefinition() }
|
||||
ParamOutNode() { outRefDef = this.getDefinitionAtNode(cfn) }
|
||||
|
||||
override DataFlowCall getCall(ReturnKind kind) {
|
||||
result = csharpCall(_, this.getDefinition().getControlFlowNode()) and
|
||||
result = csharpCall(_, cfn) and
|
||||
exists(Parameter p |
|
||||
p.getSourceDeclaration().getPosition() = kind.(OutRefReturnKind).getPosition() and
|
||||
outRefDef.getTargetAccess() = result.getExpr().(Call).getArgumentForParameter(p)
|
||||
@@ -1458,10 +1454,8 @@ class CastNode extends Node {
|
||||
CastNode() {
|
||||
this.asExpr() instanceof Cast
|
||||
or
|
||||
exists(Ssa::ExplicitDefinition def |
|
||||
def = this.(SsaDefinitionNode).getDefinition() and
|
||||
def.getADefinition() instanceof AssignableDefinitions::PatternDefinition
|
||||
)
|
||||
this.(AssignableDefinitionNode).getDefinition() instanceof
|
||||
AssignableDefinitions::PatternDefinition
|
||||
or
|
||||
readStep(_, _, this)
|
||||
or
|
||||
|
||||
@@ -19,13 +19,23 @@ class Node extends TNode {
|
||||
* if any.
|
||||
*/
|
||||
Expr asExprAtNode(ControlFlow::Nodes::ElementNode cfn) {
|
||||
this = TExprNode(cfn) and
|
||||
result = cfn.getElement()
|
||||
result = this.(ExprNode).getExprAtNode(cfn)
|
||||
}
|
||||
|
||||
/** Gets the parameter corresponding to this node, if any. */
|
||||
DotNet::Parameter asParameter() { result = this.(ParameterNode).getParameter() }
|
||||
|
||||
/** Gets the definition corresponding to this node, if any. */
|
||||
AssignableDefinition asDefinition() { result = this.asDefinitionAtNode(_) }
|
||||
|
||||
/**
|
||||
* Gets the definition corresponding to this node, at control flow node `cfn`,
|
||||
* if any.
|
||||
*/
|
||||
AssignableDefinition asDefinitionAtNode(ControlFlow::Node cfn) {
|
||||
result = this.(AssignableDefinitionNode).getDefinitionAtNode(cfn)
|
||||
}
|
||||
|
||||
/** Gets the type of this node. */
|
||||
cached
|
||||
DotNet::Type getType() { none() }
|
||||
@@ -140,6 +150,22 @@ class ParameterNode extends Node {
|
||||
predicate isParameterOf(DataFlowCallable c, int i) { none() }
|
||||
}
|
||||
|
||||
/** A definition, viewed as a node in a data flow graph. */
|
||||
class AssignableDefinitionNode extends Node, TSsaDefinitionNode {
|
||||
private Ssa::ExplicitDefinition edef;
|
||||
|
||||
AssignableDefinitionNode() { this = TSsaDefinitionNode(edef) }
|
||||
|
||||
/** Gets the underlying definition. */
|
||||
AssignableDefinition getDefinition() { result = this.getDefinitionAtNode(_) }
|
||||
|
||||
/** Gets the underlying definition, at control flow node `cfn`, if any. */
|
||||
AssignableDefinition getDefinitionAtNode(ControlFlow::Node cfn) {
|
||||
result = edef.getADefinition() and
|
||||
cfn = edef.getControlFlowNode()
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets a node corresponding to expression `e`. */
|
||||
ExprNode exprNode(DotNet::Expr e) { result.getExpr() = e }
|
||||
|
||||
@@ -148,6 +174,11 @@ ExprNode exprNode(DotNet::Expr e) { result.getExpr() = e }
|
||||
*/
|
||||
ParameterNode parameterNode(DotNet::Parameter p) { result.getParameter() = p }
|
||||
|
||||
/** Gets a node corresponding to the definition `def`. */
|
||||
AssignableDefinitionNode assignableDefinitionNode(AssignableDefinition def) {
|
||||
result.getDefinition() = def
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data flows from `nodeFrom` to `nodeTo` in exactly one local
|
||||
* (intra-procedural) step.
|
||||
|
||||
Reference in New Issue
Block a user