@@ -1756,18 +1756,31 @@ private module LocalFlowBigStep {
17561756 * Holds if `node` can be the first node in a maximal subsequence of local
17571757 * flow steps in a dataflow path.
17581758 */
1759- predicate localFlowEntry ( NodeEx node , FlowState state , Configuration config ) {
1759+ private predicate localFlowEntry ( NodeEx node , FlowState state , Configuration config ) {
17601760 Stage2:: revFlow ( node , state , config ) and
17611761 (
1762- sourceNode ( node , state , config ) or
1763- jumpStep ( _, node , config ) or
1764- additionalJumpStep ( _, node , config ) or
1765- additionalJumpStateStep ( _, _, node , state , config ) or
1766- node instanceof ParamNodeEx or
1767- node .asNode ( ) instanceof OutNodeExt or
1768- store ( _, _, node , _, config ) or
1769- read ( _, _, node , config ) or
1762+ sourceNode ( node , state , config )
1763+ or
1764+ jumpStep ( _, node , config )
1765+ or
1766+ additionalJumpStep ( _, node , config )
1767+ or
1768+ additionalJumpStateStep ( _, _, node , state , config )
1769+ or
1770+ node instanceof ParamNodeEx
1771+ or
1772+ node .asNode ( ) instanceof OutNodeExt
1773+ or
1774+ store ( _, _, node , _, config )
1775+ or
1776+ read ( _, _, node , config )
1777+ or
17701778 node instanceof FlowCheckNode
1779+ or
1780+ exists ( FlowState s |
1781+ additionalLocalStateStep ( _, s , node , state , config ) and
1782+ s != state
1783+ )
17711784 )
17721785 }
17731786
@@ -1787,6 +1800,9 @@ private module LocalFlowBigStep {
17871800 or
17881801 exists ( NodeEx next , FlowState s | Stage2:: revFlow ( next , s , config ) |
17891802 additionalJumpStateStep ( node , state , next , s , config )
1803+ or
1804+ additionalLocalStateStep ( node , state , next , s , config ) and
1805+ s != state
17901806 )
17911807 or
17921808 Stage2:: revFlow ( node , state , config ) and
@@ -1820,42 +1836,40 @@ private module LocalFlowBigStep {
18201836 */
18211837 pragma [ nomagic]
18221838 private predicate localFlowStepPlus (
1823- NodeEx node1 , FlowState state1 , NodeEx node2 , FlowState state2 , boolean preservesValue ,
1824- DataFlowType t , Configuration config , LocalCallContext cc
1839+ NodeEx node1 , FlowState state , NodeEx node2 , boolean preservesValue , DataFlowType t ,
1840+ Configuration config , LocalCallContext cc
18251841 ) {
18261842 not isUnreachableInCallCached ( node2 .asNode ( ) , cc .( LocalCallContextSpecificCall ) .getCall ( ) ) and
18271843 (
1828- localFlowEntry ( node1 , pragma [ only_bind_into ] ( state1 ) , pragma [ only_bind_into ] ( config ) ) and
1844+ localFlowEntry ( node1 , pragma [ only_bind_into ] ( state ) , pragma [ only_bind_into ] ( config ) ) and
18291845 (
18301846 localFlowStepNodeCand1 ( node1 , node2 , config ) and
1831- state1 = state2 and
18321847 preservesValue = true and
1833- t = node1 .getDataFlowType ( ) // irrelevant dummy value
1848+ t = node1 .getDataFlowType ( ) and // irrelevant dummy value
1849+ Stage2:: revFlow ( node2 , pragma [ only_bind_into ] ( state ) , pragma [ only_bind_into ] ( config ) )
18341850 or
1835- additionalLocalFlowStepNodeCand2 ( node1 , state1 , node2 , state2 , config ) and
1851+ additionalLocalFlowStepNodeCand2 ( node1 , state , node2 , state , config ) and
18361852 preservesValue = false and
18371853 t = node2 .getDataFlowType ( )
18381854 ) and
18391855 node1 != node2 and
18401856 cc .relevantFor ( node1 .getEnclosingCallable ( ) ) and
1841- not isUnreachableInCallCached ( node1 .asNode ( ) , cc .( LocalCallContextSpecificCall ) .getCall ( ) ) and
1842- Stage2:: revFlow ( node2 , pragma [ only_bind_into ] ( state2 ) , pragma [ only_bind_into ] ( config ) )
1857+ not isUnreachableInCallCached ( node1 .asNode ( ) , cc .( LocalCallContextSpecificCall ) .getCall ( ) )
18431858 or
18441859 exists ( NodeEx mid |
1845- localFlowStepPlus ( node1 , state1 , mid , pragma [ only_bind_into ] ( state2 ) , preservesValue , t ,
1860+ localFlowStepPlus ( node1 , pragma [ only_bind_into ] ( state ) , mid , preservesValue , t ,
18461861 pragma [ only_bind_into ] ( config ) , cc ) and
18471862 localFlowStepNodeCand1 ( mid , node2 , config ) and
18481863 not mid instanceof FlowCheckNode and
1849- Stage2:: revFlow ( node2 , pragma [ only_bind_into ] ( state2 ) , pragma [ only_bind_into ] ( config ) )
1864+ Stage2:: revFlow ( node2 , pragma [ only_bind_into ] ( state ) , pragma [ only_bind_into ] ( config ) )
18501865 )
18511866 or
1852- exists ( NodeEx mid , FlowState st |
1853- localFlowStepPlus ( node1 , state1 , mid , st , _, _, pragma [ only_bind_into ] ( config ) , cc ) and
1854- additionalLocalFlowStepNodeCand2 ( mid , st , node2 , state2 , config ) and
1867+ exists ( NodeEx mid |
1868+ localFlowStepPlus ( node1 , state , mid , _, _, pragma [ only_bind_into ] ( config ) , cc ) and
1869+ additionalLocalFlowStepNodeCand2 ( mid , state , node2 , state , config ) and
18551870 not mid instanceof FlowCheckNode and
18561871 preservesValue = false and
1857- t = node2 .getDataFlowType ( ) and
1858- Stage2:: revFlow ( node2 , state2 , pragma [ only_bind_into ] ( config ) )
1872+ t = node2 .getDataFlowType ( )
18591873 )
18601874 )
18611875 }
@@ -1869,9 +1883,19 @@ private module LocalFlowBigStep {
18691883 NodeEx node1 , FlowState state1 , NodeEx node2 , FlowState state2 , boolean preservesValue ,
18701884 AccessPathFrontNil apf , Configuration config , LocalCallContext callContext
18711885 ) {
1872- localFlowStepPlus ( node1 , state1 , node2 , state2 , preservesValue , apf .getType ( ) , config ,
1873- callContext ) and
1874- localFlowExit ( node2 , state2 , config )
1886+ localFlowStepPlus ( node1 , state1 , node2 , preservesValue , apf .getType ( ) , config , callContext ) and
1887+ localFlowExit ( node2 , state1 , config ) and
1888+ state1 = state2
1889+ or
1890+ additionalLocalFlowStepNodeCand2 ( node1 , state1 , node2 , state2 , config ) and
1891+ state1 != state2 and
1892+ preservesValue = false and
1893+ apf = TFrontNil ( node2 .getDataFlowType ( ) ) and
1894+ callContext .relevantFor ( node1 .getEnclosingCallable ( ) ) and
1895+ not exists ( DataFlowCall call | call = callContext .( LocalCallContextSpecificCall ) .getCall ( ) |
1896+ isUnreachableInCallCached ( node1 .asNode ( ) , call ) or
1897+ isUnreachableInCallCached ( node2 .asNode ( ) , call )
1898+ )
18751899 }
18761900}
18771901
@@ -2745,10 +2769,10 @@ private module Stage4 {
27452769
27462770 bindingset [ node, cc, config]
27472771 private LocalCc getLocalCc ( NodeEx node , Cc cc , Configuration config ) {
2748- localFlowEntry ( node , _, config ) and
27492772 result =
27502773 getLocalCallContext ( pragma [ only_bind_into ] ( pragma [ only_bind_out ] ( cc ) ) ,
2751- node .getEnclosingCallable ( ) )
2774+ node .getEnclosingCallable ( ) ) and
2775+ exists ( config )
27522776 }
27532777
27542778 private predicate localStep (
0 commit comments