Skip to content

Commit 266130b

Browse files
authored
Merge pull request #21360 from microsoft/unbreak-changes
C++: Provide `BarrierGuard` API without a `Unit` column when instantiating non-parameterized `BarrierGuard`s
2 parents 6bfb1e1 + ea9e4b3 commit 266130b

File tree

3 files changed

+70
-3
lines changed

3 files changed

+70
-3
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: breaking
3+
---
4+
* CodeQL version 2.24.2 accidentially introduced a syntactical breaking change to `BarrierGuard<...>::getAnIndirectBarrierNode` and `InstructionBarrierGuard<...>::getAnIndirectBarrierNode`. These breaking changes have now been reverted so that the original code compiles again.

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2641,7 +2641,54 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
26412641
exists(unit)
26422642
}
26432643

2644-
import ParameterizedBarrierGuard<Unit, guardChecks/4>
2644+
private module P = ParameterizedBarrierGuard<Unit, guardChecks/4>;
2645+
2646+
predicate getABarrierNode = P::getABarrierNode/0;
2647+
2648+
/**
2649+
* Gets an indirect expression node with indirection index `indirectionIndex` that is
2650+
* safely guarded by the given guard check.
2651+
*
2652+
* For example, given the following code:
2653+
* ```cpp
2654+
* int* p;
2655+
* // ...
2656+
* *p = source();
2657+
* if(is_safe_pointer(p)) {
2658+
* sink(*p);
2659+
* }
2660+
* ```
2661+
* and the following barrier guard check:
2662+
* ```ql
2663+
* predicate myGuardChecks(IRGuardCondition g, Expr e, boolean branch) {
2664+
* exists(Call call |
2665+
* g.getUnconvertedResultExpression() = call and
2666+
* call.getTarget().hasName("is_safe_pointer") and
2667+
* e = call.getAnArgument() and
2668+
* branch = true
2669+
* )
2670+
* }
2671+
* ```
2672+
* implementing `isBarrier` as:
2673+
* ```ql
2674+
* predicate isBarrier(DataFlow::Node barrier) {
2675+
* barrier = DataFlow::BarrierGuard<myGuardChecks/3>::getAnIndirectBarrierNode(1)
2676+
* }
2677+
* ```
2678+
* will block flow from `x = source()` to `sink(x)`.
2679+
*
2680+
* NOTE: If a non-indirect expression is tracked, use `getABarrierNode` instead.
2681+
*/
2682+
Node getAnIndirectBarrierNode(int indirectionIndex) {
2683+
result = P::getAnIndirectBarrierNode(indirectionIndex, _)
2684+
}
2685+
2686+
/**
2687+
* Gets an indirect expression node that is safely guarded by the given guard check.
2688+
*
2689+
* See `getAnIndirectBarrierNode/1` for examples.
2690+
*/
2691+
Node getAnIndirectBarrierNode() { result = getAnIndirectBarrierNode(_) }
26452692
}
26462693

26472694
private module InstrWithParam<ParamSig P> {
@@ -2752,7 +2799,20 @@ module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardCheck
27522799
exists(unit)
27532800
}
27542801

2755-
import ParameterizedInstructionBarrierGuard<Unit, instructionGuardChecks/4>
2802+
private module P = ParameterizedInstructionBarrierGuard<Unit, instructionGuardChecks/4>;
2803+
2804+
predicate getABarrierNode = P::getABarrierNode/0;
2805+
2806+
/**
2807+
* Gets an indirect node with indirection index `indirectionIndex` that is
2808+
* safely guarded by the given guard check.
2809+
*/
2810+
Node getAnIndirectBarrierNode(int indirectionIndex) {
2811+
result = P::getAnIndirectBarrierNode(indirectionIndex, _)
2812+
}
2813+
2814+
/** Gets an indirect node that is safely guarded by the given guard check. */
2815+
Node getAnIndirectBarrierNode() { result = getAnIndirectBarrierNode(_) }
27562816
}
27572817

27582818
/**

cpp/ql/test/library-tests/dataflow/ir-barrier-guards/test.ql

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ predicate instructionGuardChecks(IRGuardCondition gc, Instruction checked, boole
1515
module BarrierGuard = DataFlow::InstructionBarrierGuard<instructionGuardChecks/3>;
1616

1717
predicate indirectBarrierGuard(DataFlow::Node node, string s) {
18-
node = BarrierGuard::getAnIndirectBarrierNode(_) and
18+
// This any(...) could technically be removed, but it helps us verify that we don't
19+
// accidentially change the API of this predicate (for instance, by having
20+
// the column be a unit parameter).
21+
node = BarrierGuard::getAnIndirectBarrierNode(any(int indirectionIndex)) and
1922
if node.isGLValue()
2023
then s = "glval<" + node.getType().toString().replaceAll(" ", "") + ">"
2124
else s = node.getType().toString().replaceAll(" ", "")

0 commit comments

Comments
 (0)