@@ -2881,6 +2881,9 @@ module Impl<FullStateConfigSig Config> {
28812881 /** Gets the tail of this access path, if any. */
28822882 abstract AccessPath getTail ( ) ;
28832883
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+
28842887 /** Gets the front of this access path. */
28852888 abstract AccessPathFront getFront ( ) ;
28862889
@@ -2892,15 +2895,6 @@ module Impl<FullStateConfigSig Config> {
28922895
28932896 /** Gets a textual representation of this access path. */
28942897 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 ) }
29042898 }
29052899
29062900 private class AccessPathNil extends AccessPath , TAccessPathNil {
@@ -2914,6 +2908,8 @@ module Impl<FullStateConfigSig Config> {
29142908
29152909 override AccessPath getTail ( ) { none ( ) }
29162910
2911+ override predicate isCons ( TypedContent head , DataFlowType typ , AccessPath tail ) { none ( ) }
2912+
29172913 override AccessPathFrontNil getFront ( ) { result = TFrontNil ( t ) }
29182914
29192915 override AccessPathApproxNil getApprox ( ) { result = TNil ( t ) }
@@ -2924,47 +2920,51 @@ module Impl<FullStateConfigSig Config> {
29242920 }
29252921
29262922 private class AccessPathCons extends AccessPath , TAccessPathCons {
2927- private TypedContent head ;
2923+ private TypedContent head_ ;
29282924 private DataFlowType t ;
2929- private AccessPath tail ;
2925+ private AccessPath tail_ ;
2926+
2927+ AccessPathCons ( ) { this = TAccessPathCons ( head_ , t , tail_ ) }
29302928
2931- AccessPathCons ( ) { this = TAccessPathCons ( head , t , tail ) }
2929+ override TypedContent getHead ( ) { result = head_ }
29322930
2933- override TypedContent getHead ( ) { result = head }
2931+ override AccessPath getTail ( ) { result = tail_ }
29342932
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+ }
29362936
2937- override AccessPathFrontHead getFront ( ) { result = TFrontHead ( head ) }
2937+ override AccessPathFrontHead getFront ( ) { result = TFrontHead ( head_ ) }
29382938
29392939 pragma [ assume_small_delta]
29402940 override AccessPathApproxCons getApprox ( ) {
2941- result = TConsNil ( head , t ) and tail instanceof AccessPathNil
2941+ result = TConsNil ( head_ , t ) and tail_ instanceof AccessPathNil
29422942 or
2943- result = TConsCons ( head , tail .getHead ( ) , this .length ( ) )
2943+ result = TConsCons ( head_ , tail_ .getHead ( ) , this .length ( ) )
29442944 or
2945- result = TCons1 ( head , this .length ( ) )
2945+ result = TCons1 ( head_ , this .length ( ) )
29462946 }
29472947
29482948 pragma [ assume_small_delta]
2949- override int length ( ) { result = 1 + tail .length ( ) }
2949+ override int length ( ) { result = 1 + tail_ .length ( ) }
29502950
29512951 private string toStringImpl ( boolean needsSuffix ) {
2952- tail = TAccessPathNil ( _) and
2952+ tail_ = TAccessPathNil ( _) and
29532953 needsSuffix = false and
2954- result = head .toString ( ) + "]" + concat ( " : " + ppReprType ( t ) )
2954+ result = head_ .toString ( ) + "]" + concat ( " : " + ppReprType ( t ) )
29552955 or
2956- result = head + ", " + tail .( AccessPathCons ) .toStringImpl ( needsSuffix )
2956+ result = head_ + ", " + tail_ .( AccessPathCons ) .toStringImpl ( needsSuffix )
29572957 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
29602960 or
2961- result = head + ", " + tc2 + ", " + tc3 + "]" and len = 2 and needsSuffix = false
2961+ result = head_ + ", " + tc2 + ", " + tc3 + "]" and len = 2 and needsSuffix = false
29622962 )
29632963 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
29662966 or
2967- result = head + ", " + tc2 + "]" and len = 1 and needsSuffix = false
2967+ result = head_ + ", " + tc2 + "]" and len = 1 and needsSuffix = false
29682968 )
29692969 }
29702970
@@ -2991,6 +2991,14 @@ module Impl<FullStateConfigSig Config> {
29912991 result .length ( ) = len - 1
29922992 }
29932993
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+
29943002 override AccessPathFrontHead getFront ( ) { result = TFrontHead ( head1 ) }
29953003
29963004 override AccessPathApproxCons getApprox ( ) {
@@ -3010,27 +3018,32 @@ module Impl<FullStateConfigSig Config> {
30103018 }
30113019
30123020 private class AccessPathCons1 extends AccessPath , TAccessPathCons1 {
3013- private TypedContent head ;
3021+ private TypedContent head_ ;
30143022 private int len ;
30153023
3016- AccessPathCons1 ( ) { this = TAccessPathCons1 ( head , len ) }
3024+ AccessPathCons1 ( ) { this = TAccessPathCons1 ( head_ , len ) }
30173025
3018- override TypedContent getHead ( ) { result = head }
3026+ override TypedContent getHead ( ) { result = head_ }
30193027
30203028 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
30223030 }
30233031
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+ }
30253036
3026- override AccessPathApproxCons getApprox ( ) { result = TCons1 ( head , len ) }
3037+ override AccessPathFrontHead getFront ( ) { result = TFrontHead ( head_ ) }
3038+
3039+ override AccessPathApproxCons getApprox ( ) { result = TCons1 ( head_ , len ) }
30273040
30283041 override int length ( ) { result = len }
30293042
30303043 override string toString ( ) {
30313044 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 ( ) + ")]"
30343047 }
30353048 }
30363049
@@ -3421,14 +3434,17 @@ module Impl<FullStateConfigSig Config> {
34213434 t = node .getDataFlowType ( ) and
34223435 ap = TAccessPathNil ( t )
34233436 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+ )
34263442 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+ )
34323448 or
34333449 pathIntoCallable ( mid , node , state , _, cc , sc , _) and t = mid .getType ( ) and ap = mid .getAp ( )
34343450 or
@@ -3450,8 +3466,9 @@ module Impl<FullStateConfigSig Config> {
34503466
34513467 pragma [ nomagic]
34523468 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
34543470 ) {
3471+ t0 = mid .getType ( ) and
34553472 ap0 = mid .getAp ( ) and
34563473 Stage5:: storeStepCand ( mid .getNodeEx ( ) , _, tc , _, node , _, t ) and
34573474 state = mid .getState ( ) and
0 commit comments