@@ -82,47 +82,45 @@ private module VirtualDispatch {
82
82
exists ( LoadInstruction load , GlobalOrNamespaceVariable var |
83
83
var = src .asVariable ( ) and
84
84
other .asInstruction ( ) = load and
85
+ addressOfGlobal ( load .getSourceAddress ( ) , var ) and
85
86
// The `allowFromArg` concept doesn't play a role when `src` is a
86
87
// global variable, so we just set it to a single arbitrary value for
87
88
// performance.
88
89
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
98
- )
99
90
)
100
91
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`.
92
+ // Flow from store to global variable.
104
93
exists ( StoreInstruction store , GlobalOrNamespaceVariable var |
105
94
var = other .asVariable ( ) and
106
95
store = src .asInstruction ( ) and
96
+ storeIntoGlobal ( store , var ) and
107
97
// Setting `allowFromArg` to `true` like in the base case means we
108
98
// treat a store to a global variable like the dispatch itself: flow
109
99
// may come from anywhere.
110
100
allowFromArg = true
111
- |
112
- // Store directly to the global variable
113
- store .getDestinationAddress ( ) .( VariableAddressInstruction ) .getASTVariable ( ) = var
114
- or
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
120
- )
121
101
)
122
102
)
123
103
}
124
104
}
125
105
106
+ pragma [ noinline]
107
+ private predicate storeIntoGlobal ( StoreInstruction store , GlobalOrNamespaceVariable var ) {
108
+ addressOfGlobal ( store .getDestinationAddress ( ) , var )
109
+ }
110
+
111
+ /** Holds if `addressInstr` is an instruction that produces the address of `var`. */
112
+ private predicate addressOfGlobal ( Instruction addressInstr , GlobalOrNamespaceVariable var ) {
113
+ // Access directly to the global variable
114
+ addressInstr .( VariableAddressInstruction ) .getASTVariable ( ) = var
115
+ or
116
+ // Access to a field on a global union
117
+ exists ( FieldAddressInstruction fa |
118
+ fa = addressInstr and
119
+ fa .getObjectAddress ( ) .( VariableAddressInstruction ) .getASTVariable ( ) = var and
120
+ fa .getField ( ) .getDeclaringType ( ) instanceof Union
121
+ )
122
+ }
123
+
126
124
/**
127
125
* A ReturnNode with its ReturnKind and its enclosing callable.
128
126
*
0 commit comments