@@ -581,6 +581,12 @@ module RustDataFlow implements InputSig<Location> {
581581 model = ""
582582 or
583583 LocalFlow:: flowSummaryLocalStep ( nodeFrom , nodeTo , model )
584+ or
585+ // Add flow through optional barriers. This step is then blocked by the barrier for queries that choose to use the barrier.
586+ FlowSummaryImpl:: Private:: Steps:: summaryReadStep ( nodeFrom
587+ .( Node:: FlowSummaryNode )
588+ .getSummaryNode ( ) , TOptionalBarrier ( _) , nodeTo .( Node:: FlowSummaryNode ) .getSummaryNode ( ) ) and
589+ model = ""
584590 }
585591
586592 /**
@@ -710,7 +716,8 @@ module RustDataFlow implements InputSig<Location> {
710716 )
711717 or
712718 FlowSummaryImpl:: Private:: Steps:: summaryReadStep ( node1 .( FlowSummaryNode ) .getSummaryNode ( ) , cs ,
713- node2 .( FlowSummaryNode ) .getSummaryNode ( ) )
719+ node2 .( FlowSummaryNode ) .getSummaryNode ( ) ) and
720+ not isSpecialContentSet ( cs )
714721 }
715722
716723 pragma [ nomagic]
@@ -807,7 +814,8 @@ module RustDataFlow implements InputSig<Location> {
807814 storeContentStep ( node1 , cs .( SingletonContentSet ) .getContent ( ) , node2 )
808815 or
809816 FlowSummaryImpl:: Private:: Steps:: summaryStoreStep ( node1 .( FlowSummaryNode ) .getSummaryNode ( ) , cs ,
810- node2 .( FlowSummaryNode ) .getSummaryNode ( ) )
817+ node2 .( FlowSummaryNode ) .getSummaryNode ( ) ) and
818+ not isSpecialContentSet ( cs )
811819 }
812820
813821 /**
@@ -1093,7 +1101,24 @@ private module Cached {
10931101 newtype TReturnKind = TNormalReturnKind ( )
10941102
10951103 cached
1096- newtype TContentSet = TSingletonContentSet ( Content c )
1104+ newtype TContentSet =
1105+ TSingletonContentSet ( Content c ) or
1106+ TOptionalStep ( string name ) {
1107+ name = any ( FlowSummaryImpl:: Private:: AccessPathToken tok ) .getAnArgument ( "OptionalStep" )
1108+ } or
1109+ TOptionalBarrier ( string name ) {
1110+ name = any ( FlowSummaryImpl:: Private:: AccessPathToken tok ) .getAnArgument ( "OptionalBarrier" )
1111+ }
1112+
1113+ /**
1114+ * Holds if `cs` is used to encode a special operation as a content component, but should not
1115+ * be treated as an ordinary content component.
1116+ */
1117+ cached
1118+ predicate isSpecialContentSet ( ContentSet cs ) {
1119+ cs instanceof TOptionalStep or
1120+ cs instanceof TOptionalBarrier
1121+ }
10971122
10981123 /** Holds if `n` is a flow source of kind `kind`. */
10991124 cached
@@ -1105,3 +1130,22 @@ private module Cached {
11051130}
11061131
11071132import Cached
1133+
1134+ cached
1135+ private module OptionalSteps {
1136+ cached
1137+ predicate optionalStep ( Node node1 , string name , Node node2 ) {
1138+ FlowSummaryImpl:: Private:: Steps:: summaryReadStep ( node1 .( FlowSummaryNode ) .getSummaryNode ( ) ,
1139+ TOptionalStep ( name ) , node2 .( FlowSummaryNode ) .getSummaryNode ( ) ) or
1140+ FlowSummaryImpl:: Private:: Steps:: summaryStoreStep ( node1 .( FlowSummaryNode ) .getSummaryNode ( ) ,
1141+ TOptionalStep ( name ) , node2 .( FlowSummaryNode ) .getSummaryNode ( ) )
1142+ }
1143+
1144+ cached
1145+ predicate optionalBarrier ( Node node , string name ) {
1146+ FlowSummaryImpl:: Private:: Steps:: summaryReadStep ( _, TOptionalBarrier ( name ) ,
1147+ node .( FlowSummaryNode ) .getSummaryNode ( ) )
1148+ }
1149+ }
1150+
1151+ import OptionalSteps
0 commit comments