@@ -32,7 +32,9 @@ private import DataFlowImplCommon as DataFlowImplCommon
3232cached
3333private newtype TIRDataFlowNode =
3434 TNode0 ( Node0Impl node ) { DataFlowImplCommon:: forceCachingInSameStage ( ) } or
35- TVariableNode ( Variable var ) or
35+ TVariableNode ( Variable var , int indirectionIndex ) {
36+ indirectionIndex = [ 1 .. Ssa:: getMaxIndirectionsForType ( var .getUnspecifiedType ( ) ) ]
37+ } or
3638 TPostFieldUpdateNode ( FieldAddress operand , int indirectionIndex ) {
3739 indirectionIndex =
3840 [ 1 .. Ssa:: countIndirectionsForCppType ( operand .getObjectAddress ( ) .getResultLanguageType ( ) ) ]
@@ -52,7 +54,9 @@ private newtype TIRDataFlowNode =
5254 use .getParameter ( ) = p and
5355 use .getIndirectionIndex ( ) = indirectionIndex
5456 )
55- }
57+ } or
58+ TFinalGlobalValue ( Ssa:: GlobalUse globalUse ) or
59+ TInitialGlobalValue ( Ssa:: GlobalDef globalUse )
5660
5761/**
5862 * An operand that is defined by a `FieldAddressInstruction`.
@@ -279,7 +283,20 @@ class Node extends TIRDataFlowNode {
279283 * Gets the variable corresponding to this node, if any. This can be used for
280284 * modeling flow in and out of global variables.
281285 */
282- Variable asVariable ( ) { result = this .( VariableNode ) .getVariable ( ) }
286+ Variable asVariable ( ) { this = TVariableNode ( result , 1 ) }
287+
288+ /**
289+ * Gets the `indirectionIndex`'th indirection of this node's underlying variable, if any.
290+ *
291+ * This can be used for modeling flow in and out of global variables.
292+ */
293+ Variable asIndirectVariable ( int indirectionIndex ) {
294+ indirectionIndex > 1 and
295+ this = TVariableNode ( result , indirectionIndex )
296+ }
297+
298+ /** Gets an indirection of this node's underlying variable, if any. */
299+ Variable asIndirectVariable ( ) { result = this .asIndirectVariable ( _) }
283300
284301 /**
285302 * Gets the expression that is partially defined by this node, if any.
@@ -509,6 +526,66 @@ class SideEffectOperandNode extends Node, IndirectOperand {
509526 Expr getArgument ( ) { result = call .getArgument ( argumentIndex ) .getUnconvertedResultExpression ( ) }
510527}
511528
529+ /**
530+ * INTERNAL: do not use.
531+ *
532+ * A node representing the value of a global variable just before returning
533+ * from a function body.
534+ */
535+ class FinalGlobalValue extends Node , TFinalGlobalValue {
536+ Ssa:: GlobalUse globalUse ;
537+
538+ FinalGlobalValue ( ) { this = TFinalGlobalValue ( globalUse ) }
539+
540+ /** Gets the underlying SSA use. */
541+ Ssa:: GlobalUse getGlobalUse ( ) { result = globalUse }
542+
543+ override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
544+
545+ override Declaration getFunction ( ) { result = globalUse .getIRFunction ( ) .getFunction ( ) }
546+
547+ override DataFlowType getType ( ) {
548+ exists ( int indirectionIndex |
549+ indirectionIndex = globalUse .getIndirectionIndex ( ) and
550+ result = getTypeImpl ( globalUse .getUnspecifiedType ( ) , indirectionIndex - 1 )
551+ )
552+ }
553+
554+ final override Location getLocationImpl ( ) { result = globalUse .getLocation ( ) }
555+
556+ override string toStringImpl ( ) { result = globalUse .toString ( ) }
557+ }
558+
559+ /**
560+ * INTERNAL: do not use.
561+ *
562+ * A node representing the value of a global variable just after entering
563+ * a function body.
564+ */
565+ class InitialGlobalValue extends Node , TInitialGlobalValue {
566+ Ssa:: GlobalDef globalDef ;
567+
568+ InitialGlobalValue ( ) { this = TInitialGlobalValue ( globalDef ) }
569+
570+ /** Gets the underlying SSA definition. */
571+ Ssa:: GlobalDef getGlobalDef ( ) { result = globalDef }
572+
573+ override Declaration getEnclosingCallable ( ) { result = this .getFunction ( ) }
574+
575+ override Declaration getFunction ( ) { result = globalDef .getIRFunction ( ) .getFunction ( ) }
576+
577+ override DataFlowType getType ( ) {
578+ exists ( int indirectionIndex |
579+ indirectionIndex = globalDef .getIndirectionIndex ( ) and
580+ result = getTypeImpl ( globalDef .getUnspecifiedType ( ) , indirectionIndex )
581+ )
582+ }
583+
584+ final override Location getLocationImpl ( ) { result = globalDef .getLocation ( ) }
585+
586+ override string toStringImpl ( ) { result = globalDef .toString ( ) }
587+ }
588+
512589/**
513590 * INTERNAL: do not use.
514591 *
@@ -1192,12 +1269,16 @@ class DefinitionByReferenceNode extends IndirectArgumentOutNode {
11921269 */
11931270class VariableNode extends Node , TVariableNode {
11941271 Variable v ;
1272+ int indirectionIndex ;
11951273
1196- VariableNode ( ) { this = TVariableNode ( v ) }
1274+ VariableNode ( ) { this = TVariableNode ( v , indirectionIndex ) }
11971275
11981276 /** Gets the variable corresponding to this node. */
11991277 Variable getVariable ( ) { result = v }
12001278
1279+ /** Gets the indirection index of this node. */
1280+ int getIndirectionIndex ( ) { result = indirectionIndex }
1281+
12011282 override Declaration getFunction ( ) { none ( ) }
12021283
12031284 override Declaration getEnclosingCallable ( ) {
@@ -1209,11 +1290,23 @@ class VariableNode extends Node, TVariableNode {
12091290 result = v
12101291 }
12111292
1212- override DataFlowType getType ( ) { result = v .getType ( ) }
1293+ override DataFlowType getType ( ) {
1294+ result = getTypeImpl ( v .getUnspecifiedType ( ) , indirectionIndex - 1 )
1295+ }
12131296
1214- final override Location getLocationImpl ( ) { result = v .getLocation ( ) }
1297+ final override Location getLocationImpl ( ) {
1298+ // Certain variables (such as parameters) can have multiple locations.
1299+ // When there's a unique location we use that one, but if multiple locations
1300+ // exist we default to an unknown location.
1301+ result = unique( | | v .getLocation ( ) )
1302+ or
1303+ not exists ( unique( | | v .getLocation ( ) ) ) and
1304+ result instanceof UnknownDefaultLocation
1305+ }
12151306
1216- override string toStringImpl ( ) { result = v .toString ( ) }
1307+ override string toStringImpl ( ) {
1308+ if indirectionIndex = 1 then result = v .toString ( ) else result = v .toString ( ) + " indirection"
1309+ }
12171310}
12181311
12191312/**
@@ -1256,7 +1349,9 @@ DefinitionByReferenceNode definitionByReferenceNodeFromArgument(Expr argument) {
12561349}
12571350
12581351/** Gets the `VariableNode` corresponding to the variable `v`. */
1259- VariableNode variableNode ( Variable v ) { result .getVariable ( ) = v }
1352+ VariableNode variableNode ( Variable v ) {
1353+ result .getVariable ( ) = v and result .getIndirectionIndex ( ) = 1
1354+ }
12601355
12611356/**
12621357 * DEPRECATED: See UninitializedNode.
0 commit comments