@@ -83,10 +83,24 @@ private module VirtualDispatch {
8383 )
8484 or
8585 // Flow through global variable
86- exists ( StoreInstruction store , Variable var |
86+ exists ( StoreInstruction store |
8787 store = src .asInstruction ( ) and
88- var = store .getDestinationAddress ( ) .( VariableAddressInstruction ) .getASTVariable ( ) and
89- this .flowsFromGlobal ( var ) and
88+ (
89+ exists ( Variable var |
90+ var = store .getDestinationAddress ( ) .( VariableAddressInstruction ) .getASTVariable ( ) and
91+ this .flowsFromGlobal ( var )
92+ )
93+ or
94+ exists ( Variable var , FieldAccess a |
95+ var = store
96+ .getDestinationAddress ( )
97+ .( FieldAddressInstruction )
98+ .getObjectAddress ( )
99+ .( VariableAddressInstruction )
100+ .getASTVariable ( ) and
101+ this .flowsFromGlobalUnionField ( var , _, a )
102+ )
103+ ) and
90104 allowFromArg = true
91105 )
92106 }
@@ -97,6 +111,20 @@ private module VirtualDispatch {
97111 load .getSourceAddress ( ) .( VariableAddressInstruction ) .getASTVariable ( ) = var
98112 )
99113 }
114+
115+ private predicate flowsFromGlobalUnionField ( Variable var , Field f , FieldAccess a ) {
116+ f .getDeclaringType ( ) instanceof Union and
117+ exists ( LoadInstruction load |
118+ this .flowsFrom ( DataFlow:: instructionNode ( load ) , _) and
119+ a .getTarget ( ) = f and
120+ load
121+ .getSourceAddress ( )
122+ .( FieldAddressInstruction )
123+ .getObjectAddress ( )
124+ .( VariableAddressInstruction )
125+ .getASTVariable ( ) = var
126+ )
127+ }
100128 }
101129
102130 /** Call through a function pointer. */
0 commit comments