@@ -1135,8 +1135,8 @@ module Impl<FullStateConfigSig Config> {
11351135 DataFlowCall call , ArgNodeEx arg , ParamNodeEx p , boolean allowsFieldFlow
11361136 ) ;
11371137
1138- bindingset [ node, state, t , ap]
1139- predicate filter ( NodeEx node , FlowState state , Typ t , Ap ap ) ;
1138+ bindingset [ node, state, t0 , ap]
1139+ predicate filter ( NodeEx node , FlowState state , Typ t0 , Ap ap , Typ t ) ;
11401140
11411141 bindingset [ typ, contentType]
11421142 predicate typecheckStore ( Typ typ , DataFlowType contentType ) ;
@@ -1199,17 +1199,20 @@ module Impl<FullStateConfigSig Config> {
11991199 NodeEx node , FlowState state , Cc cc , ParamNodeOption summaryCtx , TypOption argT ,
12001200 ApOption argAp , Typ t , Ap ap , ApApprox apa
12011201 ) {
1202- fwdFlow0 ( node , state , cc , summaryCtx , argT , argAp , t , ap , apa ) and
1203- PrevStage:: revFlow ( node , state , apa ) and
1204- filter ( node , state , t , ap )
1202+ fwdFlow1 ( node , state , cc , summaryCtx , argT , argAp , _, t , ap , apa )
12051203 }
12061204
1207- pragma [ inline]
1208- additional predicate fwdFlow (
1205+ private predicate fwdFlow1 (
12091206 NodeEx node , FlowState state , Cc cc , ParamNodeOption summaryCtx , TypOption argT ,
1210- ApOption argAp , Typ t , Ap ap
1207+ ApOption argAp , Typ t0 , Typ t , Ap ap , ApApprox apa
12111208 ) {
1212- fwdFlow ( node , state , cc , summaryCtx , argT , argAp , t , ap , _)
1209+ fwdFlow0 ( node , state , cc , summaryCtx , argT , argAp , t0 , ap , apa ) and
1210+ PrevStage:: revFlow ( node , state , apa ) and
1211+ filter ( node , state , t0 , ap , t )
1212+ }
1213+
1214+ private predicate typeStrengthen ( Typ t0 , Ap ap , Typ t ) {
1215+ fwdFlow1 ( _, _, _, _, _, _, t0 , t , ap , _) and t0 != t
12131216 }
12141217
12151218 pragma [ assume_small_delta]
@@ -1339,6 +1342,11 @@ module Impl<FullStateConfigSig Config> {
13391342 private predicate fwdFlowConsCand ( Typ t2 , Ap cons , Content c , Typ t1 , Ap tail ) {
13401343 fwdFlowStore ( _, t1 , tail , c , t2 , _, _, _, _, _, _) and
13411344 cons = apCons ( c , t1 , tail )
1345+ or
1346+ exists ( Typ t0 |
1347+ typeStrengthen ( t0 , cons , t2 ) and
1348+ fwdFlowConsCand ( t0 , cons , c , t1 , tail )
1349+ )
13421350 }
13431351
13441352 pragma [ nomagic]
@@ -1359,7 +1367,7 @@ module Impl<FullStateConfigSig Config> {
13591367 ParamNodeOption summaryCtx , TypOption argT , ApOption argAp
13601368 ) {
13611369 exists ( ApHeadContent apc |
1362- fwdFlow ( node1 , state , cc , summaryCtx , argT , argAp , t , ap ) and
1370+ fwdFlow ( node1 , state , cc , summaryCtx , argT , argAp , t , ap , _ ) and
13631371 apc = getHeadContent ( ap ) and
13641372 readStepCand0 ( node1 , apc , c , node2 )
13651373 )
@@ -1520,14 +1528,14 @@ module Impl<FullStateConfigSig Config> {
15201528 NodeEx node , FlowState state , ReturnCtx returnCtx , ApOption returnAp , Ap ap
15211529 ) {
15221530 revFlow0 ( node , state , returnCtx , returnAp , ap ) and
1523- fwdFlow ( node , state , _, _, _, _, _, ap )
1531+ fwdFlow ( node , state , _, _, _, _, _, ap , _ )
15241532 }
15251533
15261534 pragma [ nomagic]
15271535 private predicate revFlow0 (
15281536 NodeEx node , FlowState state , ReturnCtx returnCtx , ApOption returnAp , Ap ap
15291537 ) {
1530- fwdFlow ( node , state , _, _, _, _, _, ap ) and
1538+ fwdFlow ( node , state , _, _, _, _, _, ap , _ ) and
15311539 sinkNode ( node , state ) and
15321540 (
15331541 if hasSinkCallCtx ( )
@@ -1780,13 +1788,13 @@ module Impl<FullStateConfigSig Config> {
17801788 boolean fwd , int nodes , int fields , int conscand , int states , int tuples
17811789 ) {
17821790 fwd = true and
1783- nodes = count ( NodeEx node | fwdFlow ( node , _, _, _, _, _, _, _) ) and
1791+ nodes = count ( NodeEx node | fwdFlow ( node , _, _, _, _, _, _, _, _ ) ) and
17841792 fields = count ( Content f0 | fwdConsCand ( f0 , _, _) ) and
17851793 conscand = count ( Content f0 , Typ t , Ap ap | fwdConsCand ( f0 , t , ap ) ) and
1786- states = count ( FlowState state | fwdFlow ( _, state , _, _, _, _, _, _) ) and
1794+ states = count ( FlowState state | fwdFlow ( _, state , _, _, _, _, _, _, _ ) ) and
17871795 tuples =
17881796 count ( NodeEx n , FlowState state , Cc cc , ParamNodeOption summaryCtx , TypOption argT ,
1789- ApOption argAp , Typ t , Ap ap | fwdFlow ( n , state , cc , summaryCtx , argT , argAp , t , ap ) )
1797+ ApOption argAp , Typ t , Ap ap | fwdFlow ( n , state , cc , summaryCtx , argT , argAp , t , ap , _ ) )
17901798 or
17911799 fwd = false and
17921800 nodes = count ( NodeEx node | revFlow ( node , _, _, _, _) ) and
@@ -1963,10 +1971,10 @@ module Impl<FullStateConfigSig Config> {
19631971 )
19641972 }
19651973
1966- bindingset [ node, state, t , ap]
1967- predicate filter ( NodeEx node , FlowState state , Typ t , Ap ap ) {
1974+ bindingset [ node, state, t0 , ap]
1975+ predicate filter ( NodeEx node , FlowState state , Typ t0 , Ap ap , Typ t ) {
19681976 PrevStage:: revFlowState ( state ) and
1969- exists ( t ) and
1977+ t0 = t and
19701978 exists ( ap ) and
19711979 not stateBarrier ( node , state ) and
19721980 (
@@ -2197,8 +2205,8 @@ module Impl<FullStateConfigSig Config> {
21972205 import BooleanCallContext
21982206
21992207 predicate localStep (
2200- NodeEx node1 , FlowState state1 , NodeEx node2 , FlowState state2 , boolean preservesValue ,
2201- DataFlowType t , LocalCc lcc
2208+ NodeEx node1 , FlowState state1 , NodeEx node2 , FlowState state2 , boolean preservesValue , Typ t ,
2209+ LocalCc lcc
22022210 ) {
22032211 localFlowBigStep ( node1 , state1 , node2 , state2 , preservesValue , t , _) and
22042212 exists ( lcc )
@@ -2218,10 +2226,16 @@ module Impl<FullStateConfigSig Config> {
22182226 )
22192227 }
22202228
2221- bindingset [ node, state, t , ap]
2222- predicate filter ( NodeEx node , FlowState state , Typ t , Ap ap ) {
2229+ bindingset [ node, state, t0 , ap]
2230+ predicate filter ( NodeEx node , FlowState state , Typ t0 , Ap ap , Typ t ) {
22232231 exists ( state ) and
2224- ( if castingNodeEx ( node ) then compatibleTypes ( node .getDataFlowType ( ) , t ) else any ( ) ) and
2232+ // We can get away with not using type strengthening here, since we aren't
2233+ // going to use the tracked types in the construction of Stage 4 access
2234+ // paths. For Stage 4 and onwards, the tracked types must be consistent as
2235+ // the cons candidates including types are used to construct subsequent
2236+ // access path approximations.
2237+ t0 = t and
2238+ ( if castingNodeEx ( node ) then compatibleTypes ( node .getDataFlowType ( ) , t0 ) else any ( ) ) and
22252239 (
22262240 notExpectsContent ( node )
22272241 or
@@ -2274,8 +2288,8 @@ module Impl<FullStateConfigSig Config> {
22742288
22752289 pragma [ nomagic]
22762290 predicate localStep (
2277- NodeEx node1 , FlowState state1 , NodeEx node2 , FlowState state2 , boolean preservesValue ,
2278- DataFlowType t , LocalCc lcc
2291+ NodeEx node1 , FlowState state1 , NodeEx node2 , FlowState state2 , boolean preservesValue , Typ t ,
2292+ LocalCc lcc
22792293 ) {
22802294 localFlowBigStep ( node1 , state1 , node2 , state2 , preservesValue , t , _) and
22812295 PrevStage:: revFlow ( node1 , pragma [ only_bind_into ] ( state1 ) , _) and
@@ -2333,11 +2347,18 @@ module Impl<FullStateConfigSig Config> {
23332347 )
23342348 }
23352349
2336- bindingset [ node, state, t , ap]
2337- predicate filter ( NodeEx node , FlowState state , Typ t , Ap ap ) {
2350+ bindingset [ node, state, t0 , ap]
2351+ predicate filter ( NodeEx node , FlowState state , Typ t0 , Ap ap , Typ t ) {
23382352 exists ( state ) and
23392353 not clear ( node , ap ) and
2340- ( if castingNodeEx ( node ) then compatibleTypes ( node .getDataFlowType ( ) , t ) else any ( ) ) and
2354+ (
2355+ if castingNodeEx ( node )
2356+ then
2357+ exists ( Typ nt | nt = node .getDataFlowType ( ) |
2358+ if typeStrongerThan ( nt , t0 ) then t = nt else ( compatibleTypes ( nt , t0 ) and t = t0 )
2359+ )
2360+ else t = t0
2361+ ) and
23412362 (
23422363 notExpectsContent ( node )
23432364 or
@@ -2365,7 +2386,7 @@ module Impl<FullStateConfigSig Config> {
23652386 exists ( AccessPathFront apf |
23662387 Stage4:: revFlow ( node , state , TReturnCtxMaybeFlowThrough ( _) , _, apf ) and
23672388 Stage4:: fwdFlow ( node , state , any ( Stage4:: CcCall ccc ) , _, _, TAccessPathFrontSome ( argApf ) , _,
2368- apf )
2389+ apf , _ )
23692390 )
23702391 }
23712392
@@ -2579,8 +2600,8 @@ module Impl<FullStateConfigSig Config> {
25792600 import LocalCallContext
25802601
25812602 predicate localStep (
2582- NodeEx node1 , FlowState state1 , NodeEx node2 , FlowState state2 , boolean preservesValue ,
2583- DataFlowType t , LocalCc lcc
2603+ NodeEx node1 , FlowState state1 , NodeEx node2 , FlowState state2 , boolean preservesValue , Typ t ,
2604+ LocalCc lcc
25842605 ) {
25852606 localFlowBigStep ( node1 , state1 , node2 , state2 , preservesValue , t , lcc ) and
25862607 PrevStage:: revFlow ( node1 , pragma [ only_bind_into ] ( state1 ) , _) and
@@ -2609,9 +2630,16 @@ module Impl<FullStateConfigSig Config> {
26092630 )
26102631 }
26112632
2612- bindingset [ node, state, t, ap]
2613- predicate filter ( NodeEx node , FlowState state , Typ t , Ap ap ) {
2614- ( if castingNodeEx ( node ) then compatibleTypes ( node .getDataFlowType ( ) , t ) else any ( ) ) and
2633+ bindingset [ node, state, t0, ap]
2634+ predicate filter ( NodeEx node , FlowState state , Typ t0 , Ap ap , Typ t ) {
2635+ (
2636+ if castingNodeEx ( node )
2637+ then
2638+ exists ( Typ nt | nt = node .getDataFlowType ( ) |
2639+ if typeStrongerThan ( nt , t0 ) then t = nt else ( compatibleTypes ( nt , t0 ) and t = t0 )
2640+ )
2641+ else t = t0
2642+ ) and
26152643 exists ( state ) and
26162644 exists ( ap )
26172645 }
@@ -2632,7 +2660,7 @@ module Impl<FullStateConfigSig Config> {
26322660 Stage5:: parameterMayFlowThrough ( p , _) and
26332661 Stage5:: revFlow ( n , state , TReturnCtxMaybeFlowThrough ( _) , _, apa0 ) and
26342662 Stage5:: fwdFlow ( n , state , any ( CallContextCall ccc ) , TParamNodeSome ( p .asNode ( ) ) , _,
2635- TAccessPathApproxSome ( apa ) , _, apa0 )
2663+ TAccessPathApproxSome ( apa ) , _, apa0 , _ )
26362664 )
26372665 }
26382666
@@ -2649,7 +2677,7 @@ module Impl<FullStateConfigSig Config> {
26492677 TSummaryCtxSome ( ParamNodeEx p , FlowState state , DataFlowType t , AccessPath ap ) {
26502678 exists ( AccessPathApprox apa | ap .getApprox ( ) = apa |
26512679 Stage5:: parameterMayFlowThrough ( p , apa ) and
2652- Stage5:: fwdFlow ( p , state , _, _, _, _, t , apa ) and
2680+ Stage5:: fwdFlow ( p , state , _, _, _, _, t , apa , _ ) and
26532681 Stage5:: revFlow ( p , state , _)
26542682 )
26552683 }
@@ -2820,9 +2848,7 @@ module Impl<FullStateConfigSig Config> {
28202848 ap = TAccessPathNil ( )
28212849 or
28222850 // ... or a step from an existing PathNode to another node.
2823- pathStep ( _, node , state , cc , sc , t , ap ) and
2824- Stage5:: revFlow ( node , state , ap .getApprox ( ) ) and
2825- ( if castingNodeEx ( node ) then compatibleTypes ( node .getDataFlowType ( ) , t ) else any ( ) )
2851+ pathStep ( _, node , state , cc , sc , t , ap )
28262852 } or
28272853 TPathNodeSink ( NodeEx node , FlowState state ) {
28282854 exists ( PathNodeMid sink |
@@ -3340,13 +3366,31 @@ module Impl<FullStateConfigSig Config> {
33403366 ap = mid .getAp ( )
33413367 }
33423368
3369+ private predicate pathStep (
3370+ PathNodeMid mid , NodeEx node , FlowState state , CallContext cc , SummaryCtx sc , DataFlowType t ,
3371+ AccessPath ap
3372+ ) {
3373+ exists ( DataFlowType t0 |
3374+ pathStep0 ( mid , node , state , cc , sc , t0 , ap ) and
3375+ Stage5:: revFlow ( node , state , ap .getApprox ( ) ) and
3376+ (
3377+ if castingNodeEx ( node )
3378+ then
3379+ exists ( DataFlowType nt | nt = node .getDataFlowType ( ) |
3380+ if typeStrongerThan ( nt , t0 ) then t = nt else ( compatibleTypes ( nt , t0 ) and t = t0 )
3381+ )
3382+ else t = t0
3383+ )
3384+ )
3385+ }
3386+
33433387 /**
33443388 * Holds if data may flow from `mid` to `node`. The last step in or out of
33453389 * a callable is recorded by `cc`.
33463390 */
33473391 pragma [ assume_small_delta]
33483392 pragma [ nomagic]
3349- private predicate pathStep (
3393+ private predicate pathStep0 (
33503394 PathNodeMid mid , NodeEx node , FlowState state , CallContext cc , SummaryCtx sc , DataFlowType t ,
33513395 AccessPath ap
33523396 ) {
0 commit comments