@@ -174,9 +174,21 @@ class PointerType extends @pointertype, CompositeType {
174
174
}
175
175
}
176
176
177
+ private predicate isInterfaceComponentWithQualifiedName (
178
+ InterfaceType intf , int idx , string qualifiedName , Type tp
179
+ ) {
180
+ exists ( string name | component_types ( intf , idx , name , tp ) |
181
+ interface_private_method_ids ( intf , idx , qualifiedName )
182
+ or
183
+ not interface_private_method_ids ( intf , idx , _) and qualifiedName = name
184
+ )
185
+ }
186
+
177
187
private newtype TOptInterfaceComponent =
178
188
MkNoIComponent ( ) or
179
- MkSomeIComponent ( string name , Type tp ) { component_types ( any ( InterfaceType i ) , _, name , tp ) }
189
+ MkSomeIComponent ( string name , Type tp ) {
190
+ isInterfaceComponentWithQualifiedName ( any ( InterfaceType i ) , _, name , tp )
191
+ }
180
192
181
193
private class OptInterfaceComponent extends TOptInterfaceComponent {
182
194
OptInterfaceComponent getWithDeepUnaliasedType ( ) {
@@ -196,7 +208,7 @@ private class InterfaceComponent extends MkSomeIComponent {
196
208
197
209
predicate isComponentOf ( InterfaceType intf , int i ) {
198
210
exists ( string name , Type tp |
199
- component_types ( intf , i , name , tp ) and
211
+ isInterfaceComponentWithQualifiedName ( intf , i , name , tp ) and
200
212
this = MkSomeIComponent ( name , tp )
201
213
)
202
214
}
@@ -206,10 +218,16 @@ pragma[nomagic]
206
218
predicate unpackInterfaceType (
207
219
InterfaceType intf , TOptInterfaceComponent c0 , TOptInterfaceComponent c1 ,
208
220
TOptInterfaceComponent c2 , TOptInterfaceComponent c3 , TOptInterfaceComponent c4 ,
209
- TOptInterfaceComponent e1 , TOptInterfaceComponent e2 , int nComponents , int nEmbeds
221
+ TOptInterfaceComponent e1 , TOptInterfaceComponent e2 , int nComponents , int nEmbeds ,
222
+ boolean isComparable
210
223
) {
211
- nComponents = count ( int i | component_types ( intf , i , _, _) and i >= 0 ) and
212
- nEmbeds = count ( int i | component_types ( intf , i , _, _) and i < 0 ) and
224
+ nComponents = count ( int i | isInterfaceComponentWithQualifiedName ( intf , i , _, _) and i >= 0 ) and
225
+ nEmbeds = count ( int i | isInterfaceComponentWithQualifiedName ( intf , i , _, _) and i < 0 ) and
226
+ (
227
+ if intf = any ( ComparableType comparable ) .getBaseType ( )
228
+ then isComparable = true
229
+ else isComparable = false
230
+ ) and
213
231
(
214
232
if nComponents >= 1
215
233
then c0 = any ( InterfaceComponent ic | ic .isComponentOf ( intf , 0 ) )
@@ -251,14 +269,15 @@ pragma[nomagic]
251
269
predicate unpackAndUnaliasInterfaceType (
252
270
InterfaceType intf , TOptInterfaceComponent c0 , TOptInterfaceComponent c1 ,
253
271
TOptInterfaceComponent c2 , TOptInterfaceComponent c3 , TOptInterfaceComponent c4 ,
254
- TOptInterfaceComponent e1 , TOptInterfaceComponent e2 , int nComponents , int nEmbeds
272
+ TOptInterfaceComponent e1 , TOptInterfaceComponent e2 , int nComponents , int nEmbeds ,
273
+ boolean isComparable
255
274
) {
256
275
exists (
257
276
OptInterfaceComponent c0a , OptInterfaceComponent c1a , OptInterfaceComponent c2a ,
258
277
OptInterfaceComponent c3a , OptInterfaceComponent c4a , OptInterfaceComponent e1a ,
259
278
OptInterfaceComponent e2a
260
279
|
261
- unpackInterfaceType ( intf , c0a , c1a , c2a , c3a , c4a , e1a , e2a , nComponents , nEmbeds ) and
280
+ unpackInterfaceType ( intf , c0a , c1a , c2a , c3a , c4a , e1a , e2a , nComponents , nEmbeds , isComparable ) and
262
281
c0 = c0a .getWithDeepUnaliasedType ( ) and
263
282
c1 = c1a .getWithDeepUnaliasedType ( ) and
264
283
c2 = c2a .getWithDeepUnaliasedType ( ) and
@@ -271,14 +290,29 @@ predicate unpackAndUnaliasInterfaceType(
271
290
272
291
/** An interface type. */
273
292
class InterfaceType extends @interfacetype, CompositeType {
293
+ private Type getMethodType ( int i , string name ) {
294
+ i >= 0 and isInterfaceComponentWithQualifiedName ( this , i , name , result )
295
+ }
296
+
297
+ /**
298
+ * Holds if `tp` is a directly embedded type with index `index`.
299
+ *
300
+ * `tp` (or its underlying type) is either a type set literal type or an
301
+ * interface type.
302
+ */
303
+ private predicate hasDirectlyEmbeddedType ( int index , Type tp ) {
304
+ index >= 0 and isInterfaceComponentWithQualifiedName ( this , - ( index + 1 ) , _, tp )
305
+ }
306
+
274
307
private InterfaceType getDeepUnaliasedTypeCandidate ( ) {
275
308
exists (
276
309
OptInterfaceComponent c0 , OptInterfaceComponent c1 , OptInterfaceComponent c2 ,
277
310
OptInterfaceComponent c3 , OptInterfaceComponent c4 , OptInterfaceComponent e1 ,
278
- OptInterfaceComponent e2 , int nComponents , int nEmbeds
311
+ OptInterfaceComponent e2 , int nComponents , int nEmbeds , boolean isComparable
279
312
|
280
- unpackAndUnaliasInterfaceType ( this , c0 , c1 , c2 , c3 , c4 , e1 , e2 , nComponents , nEmbeds ) and
281
- unpackInterfaceType ( result , c0 , c1 , c2 , c3 , c4 , e1 , e2 , nComponents , nEmbeds )
313
+ unpackAndUnaliasInterfaceType ( this , c0 , c1 , c2 , c3 , c4 , e1 , e2 , nComponents , nEmbeds ,
314
+ isComparable ) and
315
+ unpackInterfaceType ( result , c0 , c1 , c2 , c3 , c4 , e1 , e2 , nComponents , nEmbeds , isComparable )
282
316
)
283
317
}
284
318
@@ -289,35 +323,32 @@ class InterfaceType extends @interfacetype, CompositeType {
289
323
i = 5 or
290
324
this .hasDeepUnaliasedComponentTypesUpTo ( unaliased , i - 1 )
291
325
) and
292
- exists ( string name , Type tp | component_types ( this , i , name , tp ) |
293
- component_types ( unaliased , i , name , tp .getDeepUnaliasedType ( ) )
326
+ exists ( string name |
327
+ unaliased . getMethodType ( i , name ) = this . getMethodType ( i , name ) .getDeepUnaliasedType ( )
294
328
)
295
329
}
296
330
297
331
private predicate hasDeepUnaliasedEmbeddedTypesUpTo ( InterfaceType unaliased , int i ) {
298
332
unaliased = this .getDeepUnaliasedTypeCandidate ( ) and
299
- i >= 3 and
333
+ i >= 2 and
300
334
(
301
- i = 3 or
335
+ i = 2 or
302
336
this .hasDeepUnaliasedEmbeddedTypesUpTo ( unaliased , i - 1 )
303
337
) and
304
- exists ( string name , Type tp | component_types ( this , - i , name , tp ) |
305
- component_types ( unaliased , - i , name , tp .getDeepUnaliasedType ( ) )
338
+ exists ( Type tp | this . hasDirectlyEmbeddedType ( i , tp ) |
339
+ unaliased . hasDirectlyEmbeddedType ( i , tp .getDeepUnaliasedType ( ) )
306
340
)
307
341
}
308
342
309
343
override InterfaceType getDeepUnaliasedType ( ) {
310
344
result = this .getDeepUnaliasedTypeCandidate ( ) and
311
- exists ( int nComponents |
312
- nComponents = count ( int i | component_types ( this , i , _, _) and i >= 0 )
313
- |
345
+ exists ( int nComponents | nComponents = count ( int i | exists ( this .getMethodType ( i , _) ) ) |
314
346
this .hasDeepUnaliasedComponentTypesUpTo ( result , nComponents - 1 )
315
347
or
316
348
nComponents <= 5
317
349
) and
318
- exists ( int nEmbeds | nEmbeds = count ( int i | component_types ( this , i , _, _) and i < 0 ) |
319
- // Note no -1 here, because the first embedded type is at -1
320
- this .hasDeepUnaliasedEmbeddedTypesUpTo ( result , nEmbeds )
350
+ exists ( int nEmbeds | nEmbeds = count ( int i | this .hasDirectlyEmbeddedType ( i , _) ) |
351
+ this .hasDeepUnaliasedEmbeddedTypesUpTo ( result , nEmbeds - 1 )
321
352
or
322
353
nEmbeds <= 2
323
354
)
@@ -366,9 +397,7 @@ class TupleType extends @tupletype, CompositeType {
366
397
or
367
398
this .isDeepUnaliasedTypeUpTo ( tt , i - 1 )
368
399
) and
369
- exists ( Type tp | component_types ( this , i , _, tp ) |
370
- component_types ( tt , i , _, tp .getDeepUnaliasedType ( ) )
371
- )
400
+ tt .getComponentType ( i ) = this .getComponentType ( i ) .getDeepUnaliasedType ( )
372
401
}
373
402
374
403
override TupleType getDeepUnaliasedType ( ) {
@@ -549,6 +578,18 @@ class SendRecvChanType extends @sendrcvchantype, ChanType {
549
578
}
550
579
}
551
580
581
+ /** A named type. */
582
+ class NamedType extends @namedtype, CompositeType {
583
+ Type getBaseType ( ) { underlying_type ( this , result ) }
584
+ }
585
+
586
+ /**
587
+ * The predeclared `comparable` type.
588
+ */
589
+ class ComparableType extends NamedType {
590
+ ComparableType ( ) { typename ( this , "comparable" ) }
591
+ }
592
+
552
593
/** An alias type. */
553
594
class AliasType extends @typealias, CompositeType {
554
595
/** Gets the aliased type (i.e. that appears on the RHS of the alias definition). */
@@ -570,8 +611,6 @@ Type unalias(Type t) {
570
611
571
612
predicate containsAliases ( Type t ) { t != t .getDeepUnaliasedType ( ) }
572
613
// END ALIASES.QLL
573
-
574
-
575
614
class Object extends @object {
576
615
string toString ( ) { result = "object" }
577
616
}
@@ -582,6 +621,6 @@ class Object extends @object {
582
621
// type_objects(unique int tp: @type ref, int object: @object ref);
583
622
from Type type , Object object
584
623
where
585
- type_objects ( type , object )
586
- and not containsAliases ( type )
624
+ type_objects ( type , object ) and
625
+ not containsAliases ( type )
587
626
select type , object
0 commit comments