@@ -174,9 +174,21 @@ class PointerType extends @pointertype, CompositeType {
174174 }
175175}
176176
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+
177187private newtype TOptInterfaceComponent =
178188 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+ }
180192
181193private class OptInterfaceComponent extends TOptInterfaceComponent {
182194 OptInterfaceComponent getWithDeepUnaliasedType ( ) {
@@ -196,7 +208,7 @@ private class InterfaceComponent extends MkSomeIComponent {
196208
197209 predicate isComponentOf ( InterfaceType intf , int i ) {
198210 exists ( string name , Type tp |
199- component_types ( intf , i , name , tp ) and
211+ isInterfaceComponentWithQualifiedName ( intf , i , name , tp ) and
200212 this = MkSomeIComponent ( name , tp )
201213 )
202214 }
@@ -206,10 +218,16 @@ pragma[nomagic]
206218predicate unpackInterfaceType (
207219 InterfaceType intf , TOptInterfaceComponent c0 , TOptInterfaceComponent c1 ,
208220 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
210223) {
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
213231 (
214232 if nComponents >= 1
215233 then c0 = any ( InterfaceComponent ic | ic .isComponentOf ( intf , 0 ) )
@@ -251,14 +269,15 @@ pragma[nomagic]
251269predicate unpackAndUnaliasInterfaceType (
252270 InterfaceType intf , TOptInterfaceComponent c0 , TOptInterfaceComponent c1 ,
253271 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
255274) {
256275 exists (
257276 OptInterfaceComponent c0a , OptInterfaceComponent c1a , OptInterfaceComponent c2a ,
258277 OptInterfaceComponent c3a , OptInterfaceComponent c4a , OptInterfaceComponent e1a ,
259278 OptInterfaceComponent e2a
260279 |
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
262281 c0 = c0a .getWithDeepUnaliasedType ( ) and
263282 c1 = c1a .getWithDeepUnaliasedType ( ) and
264283 c2 = c2a .getWithDeepUnaliasedType ( ) and
@@ -271,14 +290,29 @@ predicate unpackAndUnaliasInterfaceType(
271290
272291/** An interface type. */
273292class 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+
274307 private InterfaceType getDeepUnaliasedTypeCandidate ( ) {
275308 exists (
276309 OptInterfaceComponent c0 , OptInterfaceComponent c1 , OptInterfaceComponent c2 ,
277310 OptInterfaceComponent c3 , OptInterfaceComponent c4 , OptInterfaceComponent e1 ,
278- OptInterfaceComponent e2 , int nComponents , int nEmbeds
311+ OptInterfaceComponent e2 , int nComponents , int nEmbeds , boolean isComparable
279312 |
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 )
282316 )
283317 }
284318
@@ -289,35 +323,32 @@ class InterfaceType extends @interfacetype, CompositeType {
289323 i = 5 or
290324 this .hasDeepUnaliasedComponentTypesUpTo ( unaliased , i - 1 )
291325 ) 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 ( )
294328 )
295329 }
296330
297331 private predicate hasDeepUnaliasedEmbeddedTypesUpTo ( InterfaceType unaliased , int i ) {
298332 unaliased = this .getDeepUnaliasedTypeCandidate ( ) and
299- i >= 3 and
333+ i >= 2 and
300334 (
301- i = 3 or
335+ i = 2 or
302336 this .hasDeepUnaliasedEmbeddedTypesUpTo ( unaliased , i - 1 )
303337 ) 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 ( ) )
306340 )
307341 }
308342
309343 override InterfaceType getDeepUnaliasedType ( ) {
310344 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 , _) ) ) |
314346 this .hasDeepUnaliasedComponentTypesUpTo ( result , nComponents - 1 )
315347 or
316348 nComponents <= 5
317349 ) 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 )
321352 or
322353 nEmbeds <= 2
323354 )
@@ -366,9 +397,7 @@ class TupleType extends @tupletype, CompositeType {
366397 or
367398 this .isDeepUnaliasedTypeUpTo ( tt , i - 1 )
368399 ) 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 ( )
372401 }
373402
374403 override TupleType getDeepUnaliasedType ( ) {
@@ -549,6 +578,18 @@ class SendRecvChanType extends @sendrcvchantype, ChanType {
549578 }
550579}
551580
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+
552593/** An alias type. */
553594class AliasType extends @typealias, CompositeType {
554595 /** Gets the aliased type (i.e. that appears on the RHS of the alias definition). */
@@ -570,8 +611,6 @@ Type unalias(Type t) {
570611
571612predicate containsAliases ( Type t ) { t != t .getDeepUnaliasedType ( ) }
572613// END ALIASES.QLL
573-
574-
575614class Object extends @object {
576615 string toString ( ) { result = "object" }
577616}
@@ -582,6 +621,6 @@ class Object extends @object {
582621// type_objects(unique int tp: @type ref, int object: @object ref);
583622from Type type , Object object
584623where
585- type_objects ( type , object )
586- and not containsAliases ( type )
624+ type_objects ( type , object ) and
625+ not containsAliases ( type )
587626select type , object
0 commit comments