@@ -558,15 +558,19 @@ DataFlowCallable nodeGetEnclosingCallable(Node node) {
558
558
559
559
newtype TDataFlowType =
560
560
TFunctionType ( Function f ) or
561
+ TInstanceType ( DataFlow:: ClassNode cls ) or
561
562
TAnyType ( )
562
563
563
564
class DataFlowType extends TDataFlowType {
564
565
string toDebugString ( ) {
565
- this instanceof TFunctionType and
566
566
result =
567
567
"TFunctionType(" + this .asFunction ( ) .toString ( ) + ") at line " +
568
568
this .asFunction ( ) .getLocation ( ) .getStartLine ( )
569
569
or
570
+ result =
571
+ "TInstanceType(" + this .asInstanceOfClass ( ) .toString ( ) + ") at line " +
572
+ this .asInstanceOfClass ( ) .getLocation ( ) .getStartLine ( )
573
+ or
570
574
this instanceof TAnyType and result = "TAnyType"
571
575
}
572
576
@@ -575,13 +579,25 @@ class DataFlowType extends TDataFlowType {
575
579
}
576
580
577
581
Function asFunction ( ) { this = TFunctionType ( result ) }
582
+
583
+ DataFlow:: ClassNode asInstanceOfClass ( ) { this = TInstanceType ( result ) }
584
+ }
585
+
586
+ private predicate typeStrongerThan1 ( DataFlowType t1 , DataFlowType t2 ) {
587
+ // 't1' is a subclass of 't2'
588
+ t1 .asInstanceOfClass ( ) = t2 .asInstanceOfClass ( ) .getADirectSubClass ( )
578
589
}
579
590
580
591
/**
581
592
* Holds if `t1` is strictly stronger than `t2`.
582
593
*/
583
594
predicate typeStrongerThan ( DataFlowType t1 , DataFlowType t2 ) {
584
- t1 instanceof TFunctionType and t2 = TAnyType ( )
595
+ typeStrongerThan1 ( t1 , t2 )
596
+ or
597
+ // Ensure all types are transitively stronger than 'any'
598
+ not typeStrongerThan1 ( t1 , _) and
599
+ not t1 = TAnyType ( ) and
600
+ t2 = TAnyType ( )
585
601
}
586
602
587
603
private DataFlowType getPreciseType ( Node node ) {
@@ -590,6 +606,9 @@ private DataFlowType getPreciseType(Node node) {
590
606
result = TFunctionType ( f )
591
607
)
592
608
or
609
+ result .asInstanceOfClass ( ) =
610
+ unique( DataFlow:: ClassNode cls | cls .getAnInstanceReference ( ) .getALocalUse ( ) = node )
611
+ or
593
612
result = getPreciseType ( node .getImmediatePredecessor ( ) )
594
613
or
595
614
result = getPreciseType ( node .( PostUpdateNode ) .getPreUpdateNode ( ) )
@@ -683,18 +702,27 @@ predicate neverSkipInPathGraph(Node node) {
683
702
string ppReprType ( DataFlowType t ) { none ( ) }
684
703
685
704
pragma [ inline]
686
- private predicate compatibleTypesNonSymRefl ( DataFlowType t1 , DataFlowType t2 ) {
705
+ private predicate compatibleTypesWithAny ( DataFlowType t1 , DataFlowType t2 ) {
687
706
t1 != TAnyType ( ) and
688
707
t2 = TAnyType ( )
689
708
}
690
709
710
+ pragma [ nomagic]
711
+ private predicate compatibleTypes1 ( DataFlowType t1 , DataFlowType t2 ) {
712
+ t1 .asInstanceOfClass ( ) .getADirectSubClass + ( ) = t2 .asInstanceOfClass ( )
713
+ }
714
+
691
715
pragma [ inline]
692
716
predicate compatibleTypes ( DataFlowType t1 , DataFlowType t2 ) {
693
717
t1 = t2
694
718
or
695
- compatibleTypesNonSymRefl ( t1 , t2 )
719
+ compatibleTypesWithAny ( t1 , t2 )
720
+ or
721
+ compatibleTypesWithAny ( t2 , t1 )
722
+ or
723
+ compatibleTypes1 ( t1 , t2 )
696
724
or
697
- compatibleTypesNonSymRefl ( t2 , t1 )
725
+ compatibleTypes1 ( t2 , t1 )
698
726
}
699
727
700
728
predicate forceHighPrecision ( Content c ) { none ( ) }
0 commit comments