@@ -77,49 +77,48 @@ private module VirtualDispatch {
77
77
// Local flow
78
78
DataFlow:: localFlowStep ( src , other ) and
79
79
allowFromArg = allowOtherFromArg
80
- )
81
- or
82
- // Flow through global variable
83
- exists ( StoreInstruction store |
84
- store = src .asInstruction ( ) and
85
- (
86
- exists ( Variable var |
87
- var = store .getDestinationAddress ( ) .( VariableAddressInstruction ) .getASTVariable ( ) and
88
- this .flowsFromGlobal ( var )
80
+ or
81
+ // Flow from global variable to load.
82
+ exists ( LoadInstruction load , GlobalOrNamespaceVariable var |
83
+ var = src .asVariable ( ) and
84
+ other .asInstruction ( ) = load and
85
+ // The `allowFromArg` concept doesn't play a role when `src` is a
86
+ // global variable, so we just set it to a single arbitrary value for
87
+ // performance.
88
+ allowFromArg = true
89
+ |
90
+ // Load directly from the global variable
91
+ load .getSourceAddress ( ) .( VariableAddressInstruction ) .getASTVariable ( ) = var
92
+ or
93
+ // Load from a field on a global union
94
+ exists ( FieldAddressInstruction fa |
95
+ fa = load .getSourceAddress ( ) and
96
+ fa .getObjectAddress ( ) .( VariableAddressInstruction ) .getASTVariable ( ) = var and
97
+ fa .getField ( ) .getDeclaringType ( ) instanceof Union
89
98
)
99
+ )
100
+ or
101
+ // Flow from store to global variable. These cases are similar to the
102
+ // above but have `StoreInstruction` instead of `LoadInstruction` and
103
+ // have the roles swapped between `other` and `src`.
104
+ exists ( StoreInstruction store , GlobalOrNamespaceVariable var |
105
+ var = other .asVariable ( ) and
106
+ store = src .asInstruction ( ) and
107
+ // Setting `allowFromArg` to `true` like in the base case means we
108
+ // treat a store to a global variable like the dispatch itself: flow
109
+ // may come from anywhere.
110
+ allowFromArg = true
111
+ |
112
+ // Store directly to the global variable
113
+ store .getDestinationAddress ( ) .( VariableAddressInstruction ) .getASTVariable ( ) = var
90
114
or
91
- exists ( Variable var , FieldAccess a |
92
- var =
93
- store
94
- .getDestinationAddress ( )
95
- .( FieldAddressInstruction )
96
- .getObjectAddress ( )
97
- .( VariableAddressInstruction )
98
- .getASTVariable ( ) and
99
- this .flowsFromGlobalUnionField ( var , a )
115
+ // Store to a field on a global union
116
+ exists ( FieldAddressInstruction fa |
117
+ fa = store .getDestinationAddress ( ) and
118
+ fa .getObjectAddress ( ) .( VariableAddressInstruction ) .getASTVariable ( ) = var and
119
+ fa .getField ( ) .getDeclaringType ( ) instanceof Union
100
120
)
101
- ) and
102
- allowFromArg = true
103
- )
104
- }
105
-
106
- private predicate flowsFromGlobal ( GlobalOrNamespaceVariable var ) {
107
- exists ( LoadInstruction load |
108
- this .flowsFrom ( DataFlow:: instructionNode ( load ) , _) and
109
- load .getSourceAddress ( ) .( VariableAddressInstruction ) .getASTVariable ( ) = var
110
- )
111
- }
112
-
113
- private predicate flowsFromGlobalUnionField ( Variable var , FieldAccess a ) {
114
- a .getTarget ( ) .getDeclaringType ( ) instanceof Union and
115
- exists ( LoadInstruction load |
116
- this .flowsFrom ( DataFlow:: instructionNode ( load ) , _) and
117
- load
118
- .getSourceAddress ( )
119
- .( FieldAddressInstruction )
120
- .getObjectAddress ( )
121
- .( VariableAddressInstruction )
122
- .getASTVariable ( ) = var
121
+ )
123
122
)
124
123
}
125
124
}
0 commit comments