@@ -13,7 +13,7 @@ private import semmle.code.cpp.models.interfaces.DataFlow
1313 * `Instruction`. This ensures we can add `Node`s that are not `Instruction`s
1414 * in the future.
1515 */
16- private newtype TIRDataFlowNode = MkIRDataFlowNode ( Instruction i )
16+ private newtype TIRDataFlowNode = TInstructionNode ( Instruction i )
1717
1818/**
1919 * A node in a data flow graph.
@@ -23,44 +23,39 @@ private newtype TIRDataFlowNode = MkIRDataFlowNode(Instruction i)
2323 * `DataFlow::parameterNode`, and `DataFlow::uninitializedNode` respectively.
2424 */
2525class Node extends TIRDataFlowNode {
26- Instruction instr ;
27-
28- Node ( ) { this = MkIRDataFlowNode ( instr ) }
29-
3026 /**
3127 * INTERNAL: Do not use. Alternative name for `getFunction`.
3228 */
3329 Function getEnclosingCallable ( ) { result = this .getFunction ( ) }
3430
35- Function getFunction ( ) { result = instr .getEnclosingFunction ( ) }
31+ /** Gets the function to which this node belongs. */
32+ Function getFunction ( ) { none ( ) } // overridden in subclasses
3633
3734 /** Gets the type of this node. */
38- Type getType ( ) { result = instr . getResultType ( ) }
35+ Type getType ( ) { none ( ) } // overridden in subclasses
3936
40- Instruction asInstruction ( ) { this = MkIRDataFlowNode ( result ) }
37+ /** Gets the instruction corresponding to this node, if any. */
38+ Instruction asInstruction ( ) { result = this .( InstructionNode ) .getInstruction ( ) }
4139
4240 /**
4341 * Gets the non-conversion expression corresponding to this node, if any. If
4442 * this node strictly (in the sense of `asConvertedExpr`) corresponds to a
4543 * `Conversion`, then the result is that `Conversion`'s non-`Conversion` base
4644 * expression.
4745 */
48- Expr asExpr ( ) {
49- result .getConversion * ( ) = instr .getConvertedResultExpression ( ) and
50- not result instanceof Conversion
51- }
46+ Expr asExpr ( ) { result = this .( ExprNode ) .getExpr ( ) }
5247
5348 /**
5449 * Gets the expression corresponding to this node, if any. The returned
5550 * expression may be a `Conversion`.
5651 */
57- Expr asConvertedExpr ( ) { result = instr . getConvertedResultExpression ( ) }
52+ Expr asConvertedExpr ( ) { result = this . ( ExprNode ) . getConvertedExpr ( ) }
5853
5954 /** Gets the argument that defines this `DefinitionByReferenceNode`, if any. */
6055 Expr asDefiningArgument ( ) { result = this .( DefinitionByReferenceNode ) .getArgument ( ) }
6156
6257 /** Gets the parameter corresponding to this node, if any. */
63- Parameter asParameter ( ) { result = instr . ( InitializeParameterInstruction ) .getParameter ( ) }
58+ Parameter asParameter ( ) { result = this . ( ParameterNode ) .getParameter ( ) }
6459
6560 /**
6661 * DEPRECATED: See UninitializedNode.
@@ -76,7 +71,7 @@ class Node extends TIRDataFlowNode {
7671 Type getTypeBound ( ) { result = getType ( ) }
7772
7873 /** Gets the location of this element. */
79- Location getLocation ( ) { result = instr . getLocation ( ) }
74+ Location getLocation ( ) { none ( ) } // overridden by subclasses
8075
8176 /**
8277 * Holds if this element is at the specified location.
@@ -91,32 +86,53 @@ class Node extends TIRDataFlowNode {
9186 this .getLocation ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn )
9287 }
9388
94- string toString ( ) {
89+ /** Gets a textual representation of this element. */
90+ string toString ( ) { none ( ) } // overridden by subclasses
91+ }
92+
93+ class InstructionNode extends Node , TInstructionNode {
94+ Instruction instr ;
95+
96+ InstructionNode ( ) { this = TInstructionNode ( instr ) }
97+
98+ /** Gets the instruction corresponding to this node. */
99+ Instruction getInstruction ( ) { result = instr }
100+
101+ override Function getFunction ( ) { result = instr .getEnclosingFunction ( ) }
102+
103+ override Type getType ( ) { result = instr .getResultType ( ) }
104+
105+ override Location getLocation ( ) { result = instr .getLocation ( ) }
106+
107+ override string toString ( ) {
95108 // This predicate is overridden in subclasses. This default implementation
96109 // does not use `Instruction.toString` because that's expensive to compute.
97- result = this .asInstruction ( ) .getOpcode ( ) .toString ( )
110+ result = this .getInstruction ( ) .getOpcode ( ) .toString ( )
98111 }
99112}
100113
101114/**
102115 * An expression, viewed as a node in a data flow graph.
103116 */
104- class ExprNode extends Node {
105- ExprNode ( ) { exists ( this . asExpr ( ) ) }
117+ class ExprNode extends InstructionNode {
118+ ExprNode ( ) { exists ( instr . getConvertedResultExpression ( ) ) }
106119
107120 /**
108121 * Gets the non-conversion expression corresponding to this node, if any. If
109122 * this node strictly (in the sense of `getConvertedExpr`) corresponds to a
110123 * `Conversion`, then the result is that `Conversion`'s non-`Conversion` base
111124 * expression.
112125 */
113- Expr getExpr ( ) { result = this .asExpr ( ) }
126+ Expr getExpr ( ) {
127+ result .getConversion * ( ) = instr .getConvertedResultExpression ( ) and
128+ not result instanceof Conversion
129+ }
114130
115131 /**
116132 * Gets the expression corresponding to this node, if any. The returned
117133 * expression may be a `Conversion`.
118134 */
119- Expr getConvertedExpr ( ) { result = this . asConvertedExpr ( ) }
135+ Expr getConvertedExpr ( ) { result = instr . getConvertedResultExpression ( ) }
120136
121137 override string toString ( ) { result = this .asConvertedExpr ( ) .toString ( ) }
122138}
@@ -125,7 +141,7 @@ class ExprNode extends Node {
125141 * The value of a parameter at function entry, viewed as a node in a data
126142 * flow graph.
127143 */
128- class ParameterNode extends Node {
144+ class ParameterNode extends InstructionNode {
129145 override InitializeParameterInstruction instr ;
130146
131147 /**
@@ -139,7 +155,7 @@ class ParameterNode extends Node {
139155 override string toString ( ) { result = instr .getParameter ( ) .toString ( ) }
140156}
141157
142- private class ThisParameterNode extends Node {
158+ private class ThisParameterNode extends InstructionNode {
143159 override InitializeThisInstruction instr ;
144160
145161 override string toString ( ) { result = "this" }
@@ -176,7 +192,7 @@ deprecated class UninitializedNode extends Node {
176192 * This class exists to match the interface used by Java. There are currently no non-abstract
177193 * classes that extend it. When we implement field flow, we can revisit this.
178194 */
179- abstract class PostUpdateNode extends Node {
195+ abstract class PostUpdateNode extends InstructionNode {
180196 /**
181197 * Gets the node before the state update.
182198 */
@@ -193,7 +209,7 @@ abstract class PostUpdateNode extends Node {
193209 * returned. This node will have its `getArgument()` equal to `&x` and its
194210 * `getVariableAccess()` equal to `x`.
195211 */
196- class DefinitionByReferenceNode extends Node {
212+ class DefinitionByReferenceNode extends InstructionNode {
197213 override WriteSideEffectInstruction instr ;
198214
199215 /** Gets the argument corresponding to this node. */
@@ -223,7 +239,7 @@ class DefinitionByReferenceNode extends Node {
223239/**
224240 * Gets the node corresponding to `instr`.
225241 */
226- Node instructionNode ( Instruction instr ) { result .asInstruction ( ) = instr }
242+ InstructionNode instructionNode ( Instruction instr ) { result .getInstruction ( ) = instr }
227243
228244DefinitionByReferenceNode definitionByReferenceNode ( Expr e ) { result .getArgument ( ) = e }
229245
0 commit comments