Skip to content

Commit 498395b

Browse files
committed
C++: Add QLDoc to getA(nIndirect)BarrierNode.
1 parent 8c8b919 commit 498395b

File tree

1 file changed

+65
-2
lines changed

1 file changed

+65
-2
lines changed

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

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1903,7 +1903,38 @@ signature predicate guardChecksSig(IRGuardCondition g, Expr e, boolean branch);
19031903
* in data flow and taint tracking.
19041904
*/
19051905
module BarrierGuard<guardChecksSig/3 guardChecks> {
1906-
/** Gets an expression node that is safely guarded by the given guard check. */
1906+
/**
1907+
* Gets an expression node that is safely guarded by the given guard check.
1908+
*
1909+
* For example, given the following code:
1910+
* ```cpp
1911+
* int x = source();
1912+
* // ...
1913+
* if(is_safe_int(x)) {
1914+
* sink(x);
1915+
* }
1916+
* ```
1917+
* and the following barrier guard predicate:
1918+
* ```ql
1919+
* predicate myGuardChecks(IRGuardCondition g, Expr e, boolean branch) {
1920+
* exists(Call call |
1921+
* g.getUnconvertedResultExpression() = call and
1922+
* call.getTarget().hasName("is_safe_int") and
1923+
* e = call.getAnArgument() and
1924+
* branch = true
1925+
* )
1926+
* }
1927+
* ```
1928+
* implementing `isBarrier` as:
1929+
* ```ql
1930+
* predicate isBarrier(DataFlow::Node barrier) {
1931+
* barrier = DataFlow::BarrierGuard<myGuardChecks/3>::getABarrierNode()
1932+
* }
1933+
* ```
1934+
* will block flow from `x = source()` to `sink(x)`.
1935+
*
1936+
* NOTE: If an indirect expression is tracked, use `getAnIndirectBarrierNode` instead.
1937+
*/
19071938
ExprNode getABarrierNode() {
19081939
exists(IRGuardCondition g, Expr e, ValueNumber value, boolean edge |
19091940
e = value.getAnInstruction().getConvertedResultExpression() and
@@ -1913,7 +1944,39 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
19131944
)
19141945
}
19151946

1916-
/** Gets an indirect expression node that is safely guarded by the given guard check. */
1947+
/**
1948+
* Gets an indirect expression node that is safely guarded by the given guard check.
1949+
*
1950+
* For example, given the following code:
1951+
* ```cpp
1952+
* int* p;
1953+
* // ...
1954+
* *p = source();
1955+
* if(is_safe_pointer(p)) {
1956+
* sink(*p);
1957+
* }
1958+
* ```
1959+
* and the following barrier guard check:
1960+
* ```ql
1961+
* predicate myGuardChecks(IRGuardCondition g, Expr e, boolean branch) {
1962+
* exists(Call call |
1963+
* g.getUnconvertedResultExpression() = call and
1964+
* call.getTarget().hasName("is_safe_pointer") and
1965+
* e = call.getAnArgument() and
1966+
* branch = true
1967+
* )
1968+
* }
1969+
* ```
1970+
* implementing `isBarrier` as:
1971+
* ```ql
1972+
* predicate isBarrier(DataFlow::Node barrier) {
1973+
* barrier = DataFlow::BarrierGuard<myGuardChecks/3>::getAnIndirectBarrierNode()
1974+
* }
1975+
* ```
1976+
* will block flow from `x = source()` to `sink(x)`.
1977+
*
1978+
* NOTE: If an non-indirect expression is tracked, use `getABarrierNode` instead.
1979+
*/
19171980
IndirectExprNode getAnIndirectBarrierNode() {
19181981
exists(IRGuardCondition g, Expr e, ValueNumber value, boolean edge |
19191982
e = value.getAnInstruction().getConvertedResultExpression() and

0 commit comments

Comments
 (0)