From 2cd7d385086b67541612136903367096a7156b27 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Thu, 7 Nov 2024 10:00:24 +0100 Subject: [PATCH] break --- .../lib/codeql/rust/controlflow/CfgNodes.qll | 37 +++++++++++++++++++ .../rust/controlflow/internal/CfgNodes.qll | 4 ++ 2 files changed, 41 insertions(+) diff --git a/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll index fcbb2ab4cfc0..0dd5404ebcea 100644 --- a/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/CfgNodes.qll @@ -93,3 +93,40 @@ final class BlockExprCfgNode extends Nodes::BlockExprCfgNode { */ ExprCfgNode getTailExpr() { node.hasCfgChild(node.getStmtList().getTailExpr(), this, result) } } + +/** + * A break expression. For example: + * ```rust + * loop { + * if not_ready() { + * break; + * } + * } + * ``` + * ```rust + * let x = 'label: loop { + * if done() { + * break 'label 42; + * } + * }; + * ``` + * ```rust + * let x = 'label: { + * if exit() { + * break 'label 42; + * } + * 0; + * }; + * ``` + */ +final class BreakExprCfgNode extends Nodes::BreakExprCfgNode { + /** + * Gets the target of this `break` expression. + * + * The target is either a `LoopExpr`, a `ForExpr`, a `WhileExpr`, or a + * `BlockExpr`. + */ + ExprCfgNode getTarget() { + any(BreakExprTargetChildMapping node).hasCfgChild(this.getBreakExpr(), result, this) + } +} diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/CfgNodes.qll b/rust/ql/lib/codeql/rust/controlflow/internal/CfgNodes.qll index d5328661475b..04c8e20ebf54 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/CfgNodes.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/CfgNodes.qll @@ -57,6 +57,10 @@ class BlockExprChildMapping extends ChildMapping, BlockExpr { override predicate relevantChild(AstNode child) { child = this.getStmtList().getTailExpr() } } +class BreakExprTargetChildMapping extends ChildMapping, Expr { + override predicate relevantChild(AstNode child) { child.(BreakExpr).getTarget() = this } +} + private class ChildMappingImpl extends ChildMapping { ChildMappingImpl() { exists(this) }