@@ -18,6 +18,83 @@ private Callable dispatchCand(Call c) {
1818 result = viableImpl_inp ( c )
1919}
2020
21+ /**
22+ * Holds if `t` and all its enclosing types are public.
23+ */
24+ private predicate veryPublic ( RefType t ) {
25+ t .isPublic ( ) and
26+ (
27+ not t instanceof NestedType or
28+ veryPublic ( t .( NestedType ) .getEnclosingType ( ) )
29+ )
30+ }
31+
32+ /**
33+ * Holds if `cie` occurs as the initializer of a public static field.
34+ */
35+ private predicate publicStaticFieldInit ( ClassInstanceExpr cie ) {
36+ exists ( Field f |
37+ f .isStatic ( ) and
38+ f .isPublic ( ) and
39+ veryPublic ( f .getDeclaringType ( ) ) and
40+ f .getInitializer ( ) = cie
41+ )
42+ }
43+
44+ /**
45+ * Holds if a `ClassInstanceExpr` constructing `t` occurs as the initializer of
46+ * a public static field.
47+ */
48+ private predicate publicThroughField ( RefType t ) {
49+ exists ( ClassInstanceExpr cie |
50+ cie .getConstructedType ( ) = t and
51+ publicStaticFieldInit ( cie )
52+ )
53+ }
54+
55+ /**
56+ * Holds if `t` and its subtypes are private or anonymous.
57+ */
58+ private predicate privateConstruction ( RefType t ) {
59+ ( t .isPrivate ( ) or t instanceof AnonymousClass ) and
60+ not publicThroughField ( t ) and
61+ forall ( SrcRefType sub | sub .getASourceSupertype + ( ) = t .getSourceDeclaration ( ) |
62+ ( sub .isPrivate ( ) or sub instanceof AnonymousClass ) and
63+ not publicThroughField ( sub )
64+ )
65+ }
66+
67+ /**
68+ * Holds if `m` is declared on a type that we will track all instantiations of
69+ * for the purpose of virtual dispatch to `m`. This holds in particular for
70+ * lambda methods and methods on other anonymous classes.
71+ */
72+ private predicate trackedMethod ( Method m ) {
73+ privateConstruction ( m .getDeclaringType ( ) .getSourceDeclaration ( ) )
74+ }
75+
76+ /**
77+ * Holds if `t` declares or inherits the tracked method `m`.
78+ */
79+ private predicate trackedMethodOnType ( Method m , SrcRefType t ) {
80+ exists ( Method m0 |
81+ t .hasMethod ( m0 , _, _) and
82+ m = m0 .getSourceDeclaration ( ) and
83+ trackedMethod ( m )
84+ )
85+ }
86+
87+ /**
88+ * Holds if `ma` may dispatch to the tracked method `m` declared or inherited
89+ * by the type constructed by `cie`. Thus the dispatch from `ma` to `m` will
90+ * only be included if `cie` flows to the qualifier of `ma`.
91+ */
92+ private predicate dispatchOrigin ( ClassInstanceExpr cie , MethodAccess ma , Method m ) {
93+ m = viableImpl_inp ( ma ) and
94+ not m = ma .getMethod ( ) .getSourceDeclaration ( ) and
95+ trackedMethodOnType ( m , cie .getConstructedType ( ) .getSourceDeclaration ( ) )
96+ }
97+
2198/** Holds if `t` is a type that is relevant for dispatch flow. */
2299predicate relevant ( RefType t ) {
23100 exists ( ClassInstanceExpr cie | dispatchOrigin ( cie , _, _) and t = cie .getConstructedType ( ) .getSourceDeclaration ( ) ) or
@@ -142,83 +219,6 @@ private predicate flowStep(RelevantNode n1, RelevantNode n2) {
142219 )
143220}
144221
145- /**
146- * Holds if `t` and all its enclosing types are public.
147- */
148- private predicate veryPublic ( RefType t ) {
149- t .isPublic ( ) and
150- (
151- not t instanceof NestedType or
152- veryPublic ( t .( NestedType ) .getEnclosingType ( ) )
153- )
154- }
155-
156- /**
157- * Holds if `cie` occurs as the initializer of a public static field.
158- */
159- private predicate publicStaticFieldInit ( ClassInstanceExpr cie ) {
160- exists ( Field f |
161- f .isStatic ( ) and
162- f .isPublic ( ) and
163- veryPublic ( f .getDeclaringType ( ) ) and
164- f .getInitializer ( ) = cie
165- )
166- }
167-
168- /**
169- * Holds if a `ClassInstanceExpr` constructing `t` occurs as the initializer of
170- * a public static field.
171- */
172- private predicate publicThroughField ( RefType t ) {
173- exists ( ClassInstanceExpr cie |
174- cie .getConstructedType ( ) = t and
175- publicStaticFieldInit ( cie )
176- )
177- }
178-
179- /**
180- * Holds if `t` and its subtypes are private or anonymous.
181- */
182- private predicate privateConstruction ( RefType t ) {
183- ( t .isPrivate ( ) or t instanceof AnonymousClass ) and
184- not publicThroughField ( t ) and
185- forall ( SrcRefType sub | sub .getASourceSupertype + ( ) = t .getSourceDeclaration ( ) |
186- ( sub .isPrivate ( ) or sub instanceof AnonymousClass ) and
187- not publicThroughField ( sub )
188- )
189- }
190-
191- /**
192- * Holds if `m` is declared on a type that we will track all instantiations of
193- * for the purpose of virtual dispatch to `m`. This holds in particular for
194- * lambda methods and methods on other anonymous classes.
195- */
196- private predicate trackedMethod ( Method m ) {
197- privateConstruction ( m .getDeclaringType ( ) .getSourceDeclaration ( ) )
198- }
199-
200- /**
201- * Holds if `t` declares or inherits the tracked method `m`.
202- */
203- private predicate trackedMethodOnType ( Method m , SrcRefType t ) {
204- exists ( Method m0 |
205- t .hasMethod ( m0 , _, _) and
206- m = m0 .getSourceDeclaration ( ) and
207- trackedMethod ( m )
208- )
209- }
210-
211- /**
212- * Holds if `ma` may dispatch to the tracked method `m` declared or inherited
213- * by the type constructed by `cie`. Thus the dispatch from `ma` to `m` will
214- * only be included if `cie` flows to the qualifier of `ma`.
215- */
216- private predicate dispatchOrigin ( ClassInstanceExpr cie , MethodAccess ma , Method m ) {
217- m = viableImpl_inp ( ma ) and
218- not m = ma .getMethod ( ) .getSourceDeclaration ( ) and
219- trackedMethodOnType ( m , cie .getConstructedType ( ) .getSourceDeclaration ( ) )
220- }
221-
222222/**
223223 * Holds if `n` is forward-reachable from a relevant `ClassInstanceExpr`.
224224 */
0 commit comments