@@ -2881,6 +2881,9 @@ module Impl<FullStateConfigSig Config> {
2881
2881
/** Gets the tail of this access path, if any. */
2882
2882
abstract AccessPath getTail ( ) ;
2883
2883
2884
+ /** Holds if this is a representation of `head` followed by the `typ,tail` pair. */
2885
+ abstract predicate isCons ( TypedContent head , DataFlowType typ , AccessPath tail ) ;
2886
+
2884
2887
/** Gets the front of this access path. */
2885
2888
abstract AccessPathFront getFront ( ) ;
2886
2889
@@ -2892,15 +2895,6 @@ module Impl<FullStateConfigSig Config> {
2892
2895
2893
2896
/** Gets a textual representation of this access path. */
2894
2897
abstract string toString ( ) ;
2895
-
2896
- /** Gets the access path obtained by popping `tc` from this access path, if any. */
2897
- final AccessPath pop ( TypedContent tc ) {
2898
- result = this .getTail ( ) and
2899
- tc = this .getHead ( )
2900
- }
2901
-
2902
- /** Gets the access path obtained by pushing `tc` onto this access path. */
2903
- final AccessPath push ( TypedContent tc ) { this = result .pop ( tc ) }
2904
2898
}
2905
2899
2906
2900
private class AccessPathNil extends AccessPath , TAccessPathNil {
@@ -2914,6 +2908,8 @@ module Impl<FullStateConfigSig Config> {
2914
2908
2915
2909
override AccessPath getTail ( ) { none ( ) }
2916
2910
2911
+ override predicate isCons ( TypedContent head , DataFlowType typ , AccessPath tail ) { none ( ) }
2912
+
2917
2913
override AccessPathFrontNil getFront ( ) { result = TFrontNil ( t ) }
2918
2914
2919
2915
override AccessPathApproxNil getApprox ( ) { result = TNil ( t ) }
@@ -2924,47 +2920,51 @@ module Impl<FullStateConfigSig Config> {
2924
2920
}
2925
2921
2926
2922
private class AccessPathCons extends AccessPath , TAccessPathCons {
2927
- private TypedContent head ;
2923
+ private TypedContent head_ ;
2928
2924
private DataFlowType t ;
2929
- private AccessPath tail ;
2925
+ private AccessPath tail_ ;
2926
+
2927
+ AccessPathCons ( ) { this = TAccessPathCons ( head_ , t , tail_ ) }
2930
2928
2931
- AccessPathCons ( ) { this = TAccessPathCons ( head , t , tail ) }
2929
+ override TypedContent getHead ( ) { result = head_ }
2932
2930
2933
- override TypedContent getHead ( ) { result = head }
2931
+ override AccessPath getTail ( ) { result = tail_ }
2934
2932
2935
- override AccessPath getTail ( ) { result = tail }
2933
+ override predicate isCons ( TypedContent head , DataFlowType typ , AccessPath tail ) {
2934
+ head = head_ and typ = t and tail = tail_
2935
+ }
2936
2936
2937
- override AccessPathFrontHead getFront ( ) { result = TFrontHead ( head ) }
2937
+ override AccessPathFrontHead getFront ( ) { result = TFrontHead ( head_ ) }
2938
2938
2939
2939
pragma [ assume_small_delta]
2940
2940
override AccessPathApproxCons getApprox ( ) {
2941
- result = TConsNil ( head , t ) and tail instanceof AccessPathNil
2941
+ result = TConsNil ( head_ , t ) and tail_ instanceof AccessPathNil
2942
2942
or
2943
- result = TConsCons ( head , tail .getHead ( ) , this .length ( ) )
2943
+ result = TConsCons ( head_ , tail_ .getHead ( ) , this .length ( ) )
2944
2944
or
2945
- result = TCons1 ( head , this .length ( ) )
2945
+ result = TCons1 ( head_ , this .length ( ) )
2946
2946
}
2947
2947
2948
2948
pragma [ assume_small_delta]
2949
- override int length ( ) { result = 1 + tail .length ( ) }
2949
+ override int length ( ) { result = 1 + tail_ .length ( ) }
2950
2950
2951
2951
private string toStringImpl ( boolean needsSuffix ) {
2952
- tail = TAccessPathNil ( _) and
2952
+ tail_ = TAccessPathNil ( _) and
2953
2953
needsSuffix = false and
2954
- result = head .toString ( ) + "]" + concat ( " : " + ppReprType ( t ) )
2954
+ result = head_ .toString ( ) + "]" + concat ( " : " + ppReprType ( t ) )
2955
2955
or
2956
- result = head + ", " + tail .( AccessPathCons ) .toStringImpl ( needsSuffix )
2956
+ result = head_ + ", " + tail_ .( AccessPathCons ) .toStringImpl ( needsSuffix )
2957
2957
or
2958
- exists ( TypedContent tc2 , TypedContent tc3 , int len | tail = TAccessPathCons2 ( tc2 , _, tc3 , len ) |
2959
- result = head + ", " + tc2 + ", " + tc3 + ", ... (" and len > 2 and needsSuffix = true
2958
+ exists ( TypedContent tc2 , TypedContent tc3 , int len | tail_ = TAccessPathCons2 ( tc2 , _, tc3 , len ) |
2959
+ result = head_ + ", " + tc2 + ", " + tc3 + ", ... (" and len > 2 and needsSuffix = true
2960
2960
or
2961
- result = head + ", " + tc2 + ", " + tc3 + "]" and len = 2 and needsSuffix = false
2961
+ result = head_ + ", " + tc2 + ", " + tc3 + "]" and len = 2 and needsSuffix = false
2962
2962
)
2963
2963
or
2964
- exists ( TypedContent tc2 , int len | tail = TAccessPathCons1 ( tc2 , len ) |
2965
- result = head + ", " + tc2 + ", ... (" and len > 1 and needsSuffix = true
2964
+ exists ( TypedContent tc2 , int len | tail_ = TAccessPathCons1 ( tc2 , len ) |
2965
+ result = head_ + ", " + tc2 + ", ... (" and len > 1 and needsSuffix = true
2966
2966
or
2967
- result = head + ", " + tc2 + "]" and len = 1 and needsSuffix = false
2967
+ result = head_ + ", " + tc2 + "]" and len = 1 and needsSuffix = false
2968
2968
)
2969
2969
}
2970
2970
@@ -2991,6 +2991,14 @@ module Impl<FullStateConfigSig Config> {
2991
2991
result .length ( ) = len - 1
2992
2992
}
2993
2993
2994
+ override predicate isCons ( TypedContent head , DataFlowType typ , AccessPath tail ) {
2995
+ head = head1 and
2996
+ typ = t and
2997
+ Stage5:: consCand ( head1 , t , tail .getApprox ( ) ) and
2998
+ tail .getHead ( ) = head2 and
2999
+ tail .length ( ) = len - 1
3000
+ }
3001
+
2994
3002
override AccessPathFrontHead getFront ( ) { result = TFrontHead ( head1 ) }
2995
3003
2996
3004
override AccessPathApproxCons getApprox ( ) {
@@ -3010,27 +3018,32 @@ module Impl<FullStateConfigSig Config> {
3010
3018
}
3011
3019
3012
3020
private class AccessPathCons1 extends AccessPath , TAccessPathCons1 {
3013
- private TypedContent head ;
3021
+ private TypedContent head_ ;
3014
3022
private int len ;
3015
3023
3016
- AccessPathCons1 ( ) { this = TAccessPathCons1 ( head , len ) }
3024
+ AccessPathCons1 ( ) { this = TAccessPathCons1 ( head_ , len ) }
3017
3025
3018
- override TypedContent getHead ( ) { result = head }
3026
+ override TypedContent getHead ( ) { result = head_ }
3019
3027
3020
3028
override AccessPath getTail ( ) {
3021
- Stage5:: consCand ( head , _, result .getApprox ( ) ) and result .length ( ) = len - 1
3029
+ Stage5:: consCand ( head_ , _, result .getApprox ( ) ) and result .length ( ) = len - 1
3022
3030
}
3023
3031
3024
- override AccessPathFrontHead getFront ( ) { result = TFrontHead ( head ) }
3032
+ override predicate isCons ( TypedContent head , DataFlowType typ , AccessPath tail ) {
3033
+ head = head_ and
3034
+ Stage5:: consCand ( head_ , typ , tail .getApprox ( ) ) and tail .length ( ) = len - 1
3035
+ }
3025
3036
3026
- override AccessPathApproxCons getApprox ( ) { result = TCons1 ( head , len ) }
3037
+ override AccessPathFrontHead getFront ( ) { result = TFrontHead ( head_ ) }
3038
+
3039
+ override AccessPathApproxCons getApprox ( ) { result = TCons1 ( head_ , len ) }
3027
3040
3028
3041
override int length ( ) { result = len }
3029
3042
3030
3043
override string toString ( ) {
3031
3044
if len = 1
3032
- then result = "[" + head .toString ( ) + "]"
3033
- else result = "[" + head .toString ( ) + ", ... (" + len .toString ( ) + ")]"
3045
+ then result = "[" + head_ .toString ( ) + "]"
3046
+ else result = "[" + head_ .toString ( ) + ", ... (" + len .toString ( ) + ")]"
3034
3047
}
3035
3048
}
3036
3049
@@ -3421,14 +3434,17 @@ module Impl<FullStateConfigSig Config> {
3421
3434
t = node .getDataFlowType ( ) and
3422
3435
ap = TAccessPathNil ( t )
3423
3436
or
3424
- exists ( TypedContent tc | pathStoreStep ( mid , node , state , ap .pop ( tc ) , tc , t , cc ) ) and
3425
- sc = mid .getSummaryCtx ( )
3437
+ exists ( TypedContent tc , DataFlowType t0 , AccessPath ap0 |
3438
+ pathStoreStep ( mid , node , state , t0 , ap0 , tc , t , cc ) and
3439
+ ap .isCons ( tc , t0 , ap0 ) and
3440
+ sc = mid .getSummaryCtx ( )
3441
+ )
3426
3442
or
3427
- exists ( TypedContent tc | pathReadStep ( mid , node , state , ap . push ( tc ) , tc , cc ) ) and
3428
- // TODO: replace push/pop with isCons
3429
- // ap0.isCons(tc, t, ap)
3430
- exists ( t ) and
3431
- sc = mid . getSummaryCtx ( )
3443
+ exists ( TypedContent tc , AccessPath ap0 |
3444
+ pathReadStep ( mid , node , state , ap0 , tc , cc ) and
3445
+ ap0 .isCons ( tc , t , ap ) and
3446
+ sc = mid . getSummaryCtx ( )
3447
+ )
3432
3448
or
3433
3449
pathIntoCallable ( mid , node , state , _, cc , sc , _) and t = mid .getType ( ) and ap = mid .getAp ( )
3434
3450
or
@@ -3450,8 +3466,9 @@ module Impl<FullStateConfigSig Config> {
3450
3466
3451
3467
pragma [ nomagic]
3452
3468
private predicate pathStoreStep (
3453
- PathNodeMid mid , NodeEx node , FlowState state , AccessPath ap0 , TypedContent tc , DataFlowType t , CallContext cc
3469
+ PathNodeMid mid , NodeEx node , FlowState state , DataFlowType t0 , AccessPath ap0 , TypedContent tc , DataFlowType t , CallContext cc
3454
3470
) {
3471
+ t0 = mid .getType ( ) and
3455
3472
ap0 = mid .getAp ( ) and
3456
3473
Stage5:: storeStepCand ( mid .getNodeEx ( ) , _, tc , _, node , _, t ) and
3457
3474
state = mid .getState ( ) and
0 commit comments