@@ -6,21 +6,36 @@ private import cpp
66private import semmle.code.cpp.ir.IR
77private import semmle.code.cpp.controlflow.IRGuards
88
9+ /**
10+ * A newtype wrapper to prevent accidental casts between `Node` and
11+ * `Instruction`. This ensures we can add `Node`s that are not `Instruction`s
12+ * in the future.
13+ */
14+ private newtype TIRDataFlowNode = MkIRDataFlowNode ( Instruction i )
15+
916/**
1017 * A node in a data flow graph.
1118 *
1219 * A node can be either an expression, a parameter, or an uninitialized local
1320 * variable. Such nodes are created with `DataFlow::exprNode`,
1421 * `DataFlow::parameterNode`, and `DataFlow::uninitializedNode` respectively.
1522 */
16- class Node extends Instruction {
23+ class Node extends TIRDataFlowNode {
24+ Instruction instr ;
25+
26+ Node ( ) { this = MkIRDataFlowNode ( instr ) }
27+
1728 /**
1829 * INTERNAL: Do not use. Alternative name for `getFunction`.
1930 */
20- Function getEnclosingCallable ( ) { result = this .getEnclosingFunction ( ) }
31+ Function getEnclosingCallable ( ) { result = this .getFunction ( ) }
32+
33+ Function getFunction ( ) { result = instr .getEnclosingFunction ( ) }
2134
2235 /** Gets the type of this node. */
23- Type getType ( ) { result = this .getResultType ( ) }
36+ Type getType ( ) { result = instr .getResultType ( ) }
37+
38+ Instruction asInstruction ( ) { this = MkIRDataFlowNode ( result ) }
2439
2540 /**
2641 * Gets the non-conversion expression corresponding to this node, if any. If
@@ -29,30 +44,33 @@ class Node extends Instruction {
2944 * expression.
3045 */
3146 Expr asExpr ( ) {
32- result .getConversion * ( ) = this .getConvertedResultExpression ( ) and
47+ result .getConversion * ( ) = instr .getConvertedResultExpression ( ) and
3348 not result instanceof Conversion
3449 }
3550
3651 /**
3752 * Gets the expression corresponding to this node, if any. The returned
3853 * expression may be a `Conversion`.
3954 */
40- Expr asConvertedExpr ( ) { result = this .getConvertedResultExpression ( ) }
55+ Expr asConvertedExpr ( ) { result = instr .getConvertedResultExpression ( ) }
4156
4257 /** Gets the parameter corresponding to this node, if any. */
43- Parameter asParameter ( ) { result = this .( InitializeParameterInstruction ) .getParameter ( ) }
58+ Parameter asParameter ( ) { result = instr .( InitializeParameterInstruction ) .getParameter ( ) }
4459
4560 /**
4661 * Gets the uninitialized local variable corresponding to this node, if
4762 * any.
4863 */
49- LocalVariable asUninitialized ( ) { result = this .( UninitializedInstruction ) .getLocalVariable ( ) }
64+ LocalVariable asUninitialized ( ) { result = instr .( UninitializedInstruction ) .getLocalVariable ( ) }
5065
5166 /**
5267 * Gets an upper bound on the type of this node.
5368 */
5469 Type getTypeBound ( ) { result = getType ( ) }
5570
71+ /** Gets the location of this element. */
72+ Location getLocation ( ) { result = instr .getLocation ( ) }
73+
5674 /**
5775 * Holds if this element is at the specified location.
5876 * The location spans column `startcolumn` of line `startline` to
@@ -63,8 +81,10 @@ class Node extends Instruction {
6381 predicate hasLocationInfo (
6482 string filepath , int startline , int startcolumn , int endline , int endcolumn
6583 ) {
66- getLocation ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn )
84+ this . getLocation ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn )
6785 }
86+
87+ string toString ( ) { result = instr .toString ( ) }
6888}
6989
7090/**
@@ -92,19 +112,27 @@ class ExprNode extends Node {
92112 * The value of a parameter at function entry, viewed as a node in a data
93113 * flow graph.
94114 */
95- class ParameterNode extends Node , InitializeParameterInstruction {
115+ class ParameterNode extends Node {
116+ override InitializeParameterInstruction instr ;
117+
96118 /**
97119 * Holds if this node is the parameter of `c` at the specified (zero-based)
98120 * position. The implicit `this` parameter is considered to have index `-1`.
99121 */
100- predicate isParameterOf ( Function f , int i ) { f .getParameter ( i ) = getParameter ( ) }
122+ predicate isParameterOf ( Function f , int i ) { f .getParameter ( i ) = instr .getParameter ( ) }
123+
124+ Parameter getParameter ( ) { result = instr .getParameter ( ) }
101125}
102126
103127/**
104128 * The value of an uninitialized local variable, viewed as a node in a data
105129 * flow graph.
106130 */
107- class UninitializedNode extends Node , UninitializedInstruction { }
131+ class UninitializedNode extends Node {
132+ override UninitializedInstruction instr ;
133+
134+ LocalVariable getLocalVariable ( ) { result = instr .getLocalVariable ( ) }
135+ }
108136
109137/**
110138 * A node associated with an object after an operation that might have
@@ -166,10 +194,14 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) {
166194 * data flow. It may have less flow than the `localFlowStep` predicate.
167195 */
168196predicate simpleLocalFlowStep ( Node nodeFrom , Node nodeTo ) {
169- nodeTo .( CopyInstruction ) .getSourceValue ( ) = nodeFrom or
170- nodeTo .( PhiInstruction ) .getAnOperand ( ) .getDef ( ) = nodeFrom or
197+ simpleInstructionLocalFlowStep ( nodeFrom .asInstruction ( ) , nodeTo .asInstruction ( ) )
198+ }
199+
200+ private predicate simpleInstructionLocalFlowStep ( Instruction iFrom , Instruction iTo ) {
201+ iTo .( CopyInstruction ) .getSourceValue ( ) = iFrom or
202+ iTo .( PhiInstruction ) .getAnOperand ( ) .getDef ( ) = iFrom or
171203 // Treat all conversions as flow, even conversions between different numeric types.
172- nodeTo .( ConvertInstruction ) .getUnary ( ) = nodeFrom
204+ iTo .( ConvertInstruction ) .getUnary ( ) = iFrom
173205}
174206
175207/**
0 commit comments