@@ -2859,12 +2859,16 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
28592859 Typ getTyp ( Type t ) { any ( ) }
28602860
28612861 bindingset [ c, tail]
2862- Ap apCons ( Content c , Ap tail ) { result .getAHead ( ) = c and exists ( tail ) }
2862+ Ap apCons ( Content c , Ap tail ) {
2863+ exists ( boolean isSingleton | result .getAHead ( isSingleton ) = c |
2864+ if tail instanceof ApNil then isSingleton = true else isSingleton = false
2865+ )
2866+ }
28632867
28642868 class ApHeadContent = ContentApprox ;
28652869
28662870 pragma [ noinline]
2867- ApHeadContent getHeadContent ( Ap ap ) { result = ap .getHead ( ) }
2871+ ApHeadContent getHeadContent ( Ap ap ) { result = ap .getHead ( _ ) }
28682872
28692873 predicate projectToHeadContent = getContentApproxCached / 1 ;
28702874
@@ -2910,7 +2914,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
29102914 PrevStage:: revFlow ( node ) and
29112915 PrevStage:: readStepCand ( _, c , _) and
29122916 Stage1:: expectsContentEx ( node , c ) and
2913- c = ap .getAHead ( )
2917+ c = ap .getAHead ( _ )
29142918 )
29152919 }
29162920
@@ -2961,12 +2965,17 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
29612965 Typ getTyp ( Type t ) { any ( ) }
29622966
29632967 bindingset [ c, tail]
2964- Ap apCons ( Content c , Ap tail ) { result .getHead ( ) = c and exists ( tail ) }
2968+ Ap apCons ( Content c , Ap tail ) {
2969+ exists ( boolean isSingleton |
2970+ result .getHead ( isSingleton ) = c and
2971+ if tail instanceof ApNil then isSingleton = true else isSingleton = false
2972+ )
2973+ }
29652974
29662975 class ApHeadContent = Content ;
29672976
29682977 pragma [ noinline]
2969- ApHeadContent getHeadContent ( Ap ap ) { result = ap .getHead ( ) }
2978+ ApHeadContent getHeadContent ( Ap ap ) { result = ap .getHead ( _ ) }
29702979
29712980 ApHeadContent projectToHeadContent ( Content c ) { result = c }
29722981
@@ -3012,19 +3021,19 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
30123021 // When `node` is the target of a store, we interpret `clearsContent` as
30133022 // only pertaining to _earlier_ store steps. In this case, we need to postpone
30143023 // checking `clearsContent` to the step creation.
3015- clearContent ( node , ap .getHead ( ) , false )
3024+ clearContent ( node , ap .getHead ( _ ) , false )
30163025 }
30173026
30183027 pragma [ nomagic]
3019- private predicate clearExceptStore ( Nd node , Ap ap ) { clearContent ( node , ap .getHead ( ) , true ) }
3028+ private predicate clearExceptStore ( Nd node , Ap ap ) { clearContent ( node , ap .getHead ( _ ) , true ) }
30203029
30213030 pragma [ nomagic]
30223031 private predicate expectsContentCand ( Nd node , Ap ap ) {
30233032 exists ( Content c |
30243033 PrevStage:: revFlow ( node ) and
30253034 PrevStage:: readStepCand ( _, c , _) and
30263035 Stage1:: expectsContentEx ( node , c ) and
3027- c = ap .getHead ( )
3036+ c = ap .getHead ( _ )
30283037 )
30293038 }
30303039
@@ -3059,9 +3068,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
30593068 tails = strictcount ( AccessPathFront apf | Stage4:: consCand ( c , apf ) ) and
30603069 nodes =
30613070 strictcount ( Nd n |
3062- Stage4:: revFlow ( n , any ( AccessPathFrontHead apf | apf .getHead ( ) = c ) )
3071+ Stage4:: revFlow ( n , any ( AccessPathFrontHead apf | apf .getHead ( _ ) = c ) )
30633072 or
3064- Stage4:: nodeMayUseSummary ( n , any ( AccessPathFrontHead apf | apf .getHead ( ) = c ) )
3073+ Stage4:: nodeMayUseSummary ( n , any ( AccessPathFrontHead apf | apf .getHead ( _ ) = c ) )
30653074 ) and
30663075 accessPathApproxCostLimits ( apLimit , tupleLimit ) and
30673076 apLimit < tails and
@@ -3077,7 +3086,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
30773086 not expensiveLen2unfolding ( c )
30783087 } or
30793088 TConsCons ( Content c1 , Content c2 , int len ) {
3080- Stage4:: consCand ( c1 , TFrontHead ( c2 ) ) and
3089+ Stage4:: consCand ( c1 , TFrontHead ( c2 , _ ) ) and
30813090 len in [ 2 .. Config:: accessPathLimit ( ) ] and
30823091 not expensiveLen2unfolding ( c1 )
30833092 } or
@@ -3131,7 +3140,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
31313140
31323141 override int len ( ) { result = 1 }
31333142
3134- override AccessPathFront getFront ( ) { result = TFrontHead ( c ) }
3143+ override AccessPathFront getFront ( ) { result = TFrontHead ( c , true ) }
31353144
31363145 override predicate isCons ( Content head , AccessPathApprox tail ) { head = c and tail = TNil ( ) }
31373146 }
@@ -3153,7 +3162,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
31533162
31543163 override int len ( ) { result = len }
31553164
3156- override AccessPathFront getFront ( ) { result = TFrontHead ( c1 ) }
3165+ override AccessPathFront getFront ( ) { result = TFrontHead ( c1 , false ) }
31573166
31583167 override predicate isCons ( Content head , AccessPathApprox tail ) {
31593168 head = c1 and
@@ -3184,12 +3193,14 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
31843193
31853194 override int len ( ) { result = len }
31863195
3187- override AccessPathFront getFront ( ) { result = TFrontHead ( c ) }
3196+ override AccessPathFront getFront ( ) {
3197+ if len = 1 then result = TFrontHead ( c , true ) else result = TFrontHead ( c , false )
3198+ }
31883199
31893200 override predicate isCons ( Content head , AccessPathApprox tail ) {
31903201 head = c and
31913202 (
3192- exists ( Content c2 | Stage4:: consCand ( c , TFrontHead ( c2 ) ) |
3203+ exists ( Content c2 | Stage4:: consCand ( c , TFrontHead ( c2 , _ ) ) |
31933204 tail = TConsCons ( c2 , _, len - 1 )
31943205 or
31953206 len = 2 and
@@ -3531,7 +3542,11 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
35313542
35323543 override predicate isCons ( Content head , AccessPath tail ) { head = head_ and tail = tail_ }
35333544
3534- override AccessPathFrontHead getFront ( ) { result = TFrontHead ( head_ ) }
3545+ override AccessPathFrontHead getFront ( ) {
3546+ if tail_ .length ( ) = 0
3547+ then result = TFrontHead ( head_ , true )
3548+ else result = TFrontHead ( head_ , false )
3549+ }
35353550
35363551 override AccessPathApproxCons getApprox ( ) {
35373552 result = TConsNil ( head_ ) and tail_ = TAccessPathNil ( )
@@ -3586,7 +3601,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
35863601 tail .length ( ) = len - 1
35873602 }
35883603
3589- override AccessPathFrontHead getFront ( ) { result = TFrontHead ( head1 ) }
3604+ override AccessPathFrontHead getFront ( ) { result = TFrontHead ( head1 , false ) }
35903605
35913606 override AccessPathApproxCons getApprox ( ) {
35923607 result = TConsCons ( head1 , head2 , len ) or
@@ -3618,7 +3633,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
36183633 tail .length ( ) = len - 1
36193634 }
36203635
3621- override AccessPathFrontHead getFront ( ) { result = TFrontHead ( head_ ) }
3636+ override AccessPathFrontHead getFront ( ) {
3637+ if len = 1 then result = TFrontHead ( head_ , true ) else result = TFrontHead ( head_ , false )
3638+ }
36223639
36233640 override AccessPathApproxCons getApprox ( ) { result = TCons1 ( head_ , len ) }
36243641
0 commit comments