@@ -147,9 +147,8 @@ abstract class Configuration extends string {
147147 */
148148 predicate isBarrier ( DataFlow:: Node node ) {
149149 exists ( BarrierGuardNode guard |
150- not guard instanceof LabeledBarrierGuardNode and
151150 isBarrierGuard ( guard ) and
152- guard .blocks ( node )
151+ guard .internalBlocks ( node , "" )
153152 )
154153 }
155154
@@ -167,10 +166,9 @@ abstract class Configuration extends string {
167166 * Holds if flow with label `lbl` cannot flow into `node`.
168167 */
169168 predicate isLabeledBarrier ( DataFlow:: Node node , FlowLabel lbl ) {
170- exists ( LabeledBarrierGuardNode guard |
171- lbl = guard .getALabel ( ) and
169+ exists ( BarrierGuardNode guard |
172170 isBarrierGuard ( guard ) and
173- guard .blocks ( node )
171+ guard .internalBlocks ( node , lbl )
174172 )
175173 or
176174 none ( ) // relax type inference to account for overriding
@@ -254,43 +252,81 @@ module FlowLabel {
254252 */
255253abstract class BarrierGuardNode extends DataFlow:: Node {
256254 /**
257- * Holds if data flow node `nd` acts as a barrier for data flow.
255+ * Holds if data flow node `nd` acts as a barrier for data flow, possibly due to aliasing
256+ * through an access path.
257+ *
258+ * `label` is bound to the blocked label, or the empty string if all labels should be blocked.
258259 *
259260 * INTERNAL: this predicate should only be used from within `blocks(boolean, Expr)`.
260261 */
261- predicate blocks ( DataFlow:: Node nd ) {
262+ predicate internalBlocks ( DataFlow:: Node nd , string label ) {
262263 // 1) `nd` is a use of a refinement node that blocks its input variable
263- exists ( SsaRefinementNode ref |
264+ exists ( SsaRefinementNode ref , boolean outcome |
264265 nd = DataFlow:: ssaDefinitionNode ( ref ) and
265266 forex ( SsaVariable input | input = ref .getAnInput ( ) |
266267 asExpr ( ) = ref .getGuard ( ) .getTest ( ) and
267- blocks ( ref .getGuard ( ) .( ConditionGuardNode ) .getOutcome ( ) , input .getAUse ( ) )
268+ outcome = ref .getGuard ( ) .( ConditionGuardNode ) .getOutcome ( ) and
269+ internalBlocksExpr ( outcome , input .getAUse ( ) , label )
268270 )
269271 )
270272 or
271273 // 2) `nd` is an instance of an access path `p`, and dominated by a barrier for `p`
272- exists ( AccessPath p , BasicBlock bb , ConditionGuardNode cond |
274+ exists ( AccessPath p , BasicBlock bb , ConditionGuardNode cond , boolean outcome |
273275 nd = DataFlow:: valueNode ( p .getAnInstanceIn ( bb ) ) and
274276 asExpr ( ) = cond .getTest ( ) and
275- blocks ( cond .getOutcome ( ) , p .getAnInstance ( ) ) and
277+ outcome = cond .getOutcome ( ) and
278+ internalBlocksAccessPath ( outcome , p , label ) and
276279 cond .dominates ( bb )
277280 )
278281 }
279282
283+ /**
284+ * Holds if data flow node `nd` acts as a barrier for data flow.
285+ *
286+ * `label` is bound to the blocked label, or the empty string if all labels should be blocked.
287+ */
288+ private predicate internalBlocksExpr ( boolean outcome , Expr test , string label ) {
289+ blocks ( outcome , test ) and label = ""
290+ or
291+ blocks ( outcome , test , label )
292+ }
293+
294+ /**
295+ * Holds if data flow node `nd` acts as a barrier for data flow due to aliasing through
296+ * an access path.
297+ *
298+ * `label` is bound to the blocked label, or the empty string if all labels should be blocked.
299+ */
300+ pragma [ noinline]
301+ private predicate internalBlocksAccessPath ( boolean outcome , AccessPath ap , string label ) {
302+ internalBlocksExpr ( outcome , ap .getAnInstance ( ) , label )
303+ }
304+
280305 /**
281306 * Holds if this node blocks expression `e` provided it evaluates to `outcome`.
307+ *
308+ * This will block all flow labels.
282309 */
283310 abstract predicate blocks ( boolean outcome , Expr e ) ;
311+
312+ /**
313+ * Holds if this node blocks expression `e` from flow of type `label`, provided it evaluates to `outcome`.
314+ */
315+ predicate blocks ( boolean outcome , Expr e , FlowLabel label ) { none ( ) }
284316}
285317
286318/**
287319 * A guard node that only blocks specific labels.
288320 */
289321abstract class LabeledBarrierGuardNode extends BarrierGuardNode {
322+ override predicate blocks ( boolean outcome , Expr e ) { none ( ) }
323+
290324 /**
291- * Get a flow label blocked by this guard node.
325+ * DEPRECATED: Use `blocks(outcome, e, label)` or `sanitizes(outcome, e, label)` instead.
326+ *
327+ * Overriding this predicate has no effect.
292328 */
293- abstract FlowLabel getALabel ( ) ;
329+ deprecated FlowLabel getALabel ( ) { none ( ) }
294330}
295331
296332/**
0 commit comments