mirror of
https://github.com/github/codeql.git
synced 2025-12-22 11:46:32 +01:00
C++: Add VariableNode
This commit is contained in:
@@ -185,7 +185,13 @@ class CastNode extends InstructionNode {
|
||||
CastNode() { none() } // stub implementation
|
||||
}
|
||||
|
||||
class DataFlowCallable = Function;
|
||||
/**
|
||||
* A function that may contain code or a variable that may contain itself. When
|
||||
* flow crosses from one _enclosing callable_ to another, the interprocedural
|
||||
* data-flow library discards call contexts and inserts a node in the big-step
|
||||
* relation used for human-readable path explanations.
|
||||
*/
|
||||
class DataFlowCallable = Declaration;
|
||||
|
||||
class DataFlowExpr = Expr;
|
||||
|
||||
|
||||
@@ -8,12 +8,9 @@ private import semmle.code.cpp.controlflow.IRGuards
|
||||
private import semmle.code.cpp.ir.ValueNumbering
|
||||
private import semmle.code.cpp.models.interfaces.DataFlow
|
||||
|
||||
/**
|
||||
* A newtype wrapper to prevent accidental casts between `Node` and
|
||||
* `Instruction`. This ensures we can add `Node`s that are not `Instruction`s
|
||||
* in the future.
|
||||
*/
|
||||
private newtype TIRDataFlowNode = TInstructionNode(Instruction i)
|
||||
private newtype TIRDataFlowNode =
|
||||
TInstructionNode(Instruction i) or
|
||||
TVariableNode(Variable var)
|
||||
|
||||
/**
|
||||
* A node in a data flow graph.
|
||||
@@ -24,11 +21,11 @@ private newtype TIRDataFlowNode = TInstructionNode(Instruction i)
|
||||
*/
|
||||
class Node extends TIRDataFlowNode {
|
||||
/**
|
||||
* INTERNAL: Do not use. Alternative name for `getFunction`.
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
Function getEnclosingCallable() { result = this.getFunction() }
|
||||
Declaration getEnclosingCallable() { none() } // overridden in subclasses
|
||||
|
||||
/** Gets the function to which this node belongs. */
|
||||
/** Gets the function to which this node belongs, if any. */
|
||||
Function getFunction() { none() } // overridden in subclasses
|
||||
|
||||
/** Gets the type of this node. */
|
||||
@@ -57,6 +54,12 @@ class Node extends TIRDataFlowNode {
|
||||
/** Gets the parameter corresponding to this node, if any. */
|
||||
Parameter asParameter() { result = this.(ParameterNode).getParameter() }
|
||||
|
||||
/**
|
||||
* Gets the variable corresponding to this node, if any. This can be used for
|
||||
* modelling flow in and out of global variables.
|
||||
*/
|
||||
Variable asVariable() { result = this.(VariableNode).getVariable() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: See UninitializedNode.
|
||||
*
|
||||
@@ -98,6 +101,8 @@ class InstructionNode extends Node, TInstructionNode {
|
||||
/** Gets the instruction corresponding to this node. */
|
||||
Instruction getInstruction() { result = instr }
|
||||
|
||||
override Declaration getEnclosingCallable() { result = this.getFunction() }
|
||||
|
||||
override Function getFunction() { result = instr.getEnclosingFunction() }
|
||||
|
||||
override Type getType() { result = instr.getResultType() }
|
||||
@@ -236,6 +241,37 @@ class DefinitionByReferenceNode extends InstructionNode {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A `Node` corresponding to a variable in the program, as opposed to the
|
||||
* value of that variable at some particular point. This can be used for
|
||||
* modelling flow in and out of global variables.
|
||||
*/
|
||||
class VariableNode extends Node, TVariableNode {
|
||||
Variable v;
|
||||
|
||||
VariableNode() { this = TVariableNode(v) }
|
||||
|
||||
/** Gets the variable corresponding to this node. */
|
||||
Variable getVariable() { result = v }
|
||||
|
||||
override Function getFunction() { none() }
|
||||
|
||||
override Declaration getEnclosingCallable() {
|
||||
// When flow crosses from one _enclosing callable_ to another, the
|
||||
// interprocedural data-flow library discards call contexts and inserts a
|
||||
// node in the big-step relation used for human-readable path explanations.
|
||||
// Therefore we want a distinct enclosing callable for each `VariableNode`,
|
||||
// and that can be the `Variable` itself.
|
||||
result = v
|
||||
}
|
||||
|
||||
override Type getType() { result = v.getType() }
|
||||
|
||||
override Location getLocation() { result = v.getLocation() }
|
||||
|
||||
override string toString() { result = v.toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the node corresponding to `instr`.
|
||||
*/
|
||||
@@ -260,6 +296,9 @@ ExprNode convertedExprNode(Expr e) { result.getExpr() = e }
|
||||
*/
|
||||
ParameterNode parameterNode(Parameter p) { result.getParameter() = p }
|
||||
|
||||
/** Gets the `VariableNode` corresponding to the variable `v`. */
|
||||
VariableNode variableNode(Variable v) { result.getVariable() = v }
|
||||
|
||||
/**
|
||||
* Gets the `Node` corresponding to the value of an uninitialized local
|
||||
* variable `v`.
|
||||
|
||||
Reference in New Issue
Block a user