@@ -1903,7 +1903,38 @@ signature predicate guardChecksSig(IRGuardCondition g, Expr e, boolean branch);
19031903 * in data flow and taint tracking.
19041904 */
19051905module 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