From 15af6c1b20ebbb3b4016e11e6e7e9af9ec626f45 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 24 Feb 2026 12:32:23 +0000 Subject: [PATCH] C++: Provide barrier node API without the unit column when instantiating non-parameterized barrier guards. --- .../cpp/ir/dataflow/internal/DataFlowUtil.qll | 64 ++++++++++++++++++- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index 9bc3a80e3e0..d704c7d56d6 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -2641,7 +2641,54 @@ module BarrierGuard { exists(unit) } - import ParameterizedBarrierGuard + private module P = ParameterizedBarrierGuard; + + predicate getABarrierNode = P::getABarrierNode/0; + + /** + * Gets an indirect expression node with indirection index `indirectionIndex` that is + * safely guarded by the given guard check. + * + * For example, given the following code: + * ```cpp + * int* p; + * // ... + * *p = source(); + * if(is_safe_pointer(p)) { + * sink(*p); + * } + * ``` + * and the following barrier guard check: + * ```ql + * predicate myGuardChecks(IRGuardCondition g, Expr e, boolean branch) { + * exists(Call call | + * g.getUnconvertedResultExpression() = call and + * call.getTarget().hasName("is_safe_pointer") and + * e = call.getAnArgument() and + * branch = true + * ) + * } + * ``` + * implementing `isBarrier` as: + * ```ql + * predicate isBarrier(DataFlow::Node barrier) { + * barrier = DataFlow::BarrierGuard::getAnIndirectBarrierNode(1) + * } + * ``` + * will block flow from `x = source()` to `sink(x)`. + * + * NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead. + */ + Node getAnIndirectBarrierNode(int indirectionIndex) { + result = P::getAnIndirectBarrierNode(indirectionIndex, _) + } + + /** + * Gets an indirect expression node that is safely guarded by the given guard check. + * + * See `getAnIndirectBarrierNode/1` for examples. + */ + Node getAnIndirectBarrierNode() { result = getAnIndirectBarrierNode(_) } } private module InstrWithParam { @@ -2752,7 +2799,20 @@ module InstructionBarrierGuard + private module P = ParameterizedInstructionBarrierGuard; + + predicate getABarrierNode = P::getABarrierNode/0; + + /** + * Gets an indirect node with indirection index `indirectionIndex` that is + * safely guarded by the given guard check. + */ + Node getAnIndirectBarrierNode(int indirectionIndex) { + result = P::getAnIndirectBarrierNode(indirectionIndex, _) + } + + /** Gets an indirect node that is safely guarded by the given guard check. */ + Node getAnIndirectBarrierNode() { result = getAnIndirectBarrierNode(_) } } /**