@@ -12,19 +12,29 @@ import rust
1212import codeql.rust.controlflow.ControlFlowGraph
1313import codeql.rust.controlflow.internal.ControlFlowGraphImpl as ControlFlowGraphImpl
1414
15+ /**
16+ * Holds if `n` is an AST node that's unreachable.
17+ */
18+ private predicate unreachable ( AstNode n ) {
19+ not n = any ( CfgNode cfn ) .getAstNode ( )
20+ }
21+
1522/**
1623 * Holds if `n` is an AST node that's unreachable, and is not the successor
1724 * of an unreachable node (which would be a duplicate result).
1825 */
19- predicate firstUnreachable ( AstNode n ) {
20- // entry nodes are reachable
21- not exists ( CfgScope s | s .scopeFirst ( n ) ) and
22- // we never want a `ControlFlowTree` successor node:
23- // - if the predecessor is reachable, so are we.
24- // - if the predecessor is unreachable, we're not the *first* unreachable node.
25- not ControlFlowGraphImpl:: succ ( _, n , _)
26- // (note that an unreachable cycle of nodes could be missed by this logic, in
27- // general it wouldn't be possible to pick one node to represent it)
26+ private predicate firstUnreachable ( AstNode n ) {
27+ unreachable ( n ) and
28+ (
29+ // no predecessor -> we are the first unreachable node.
30+ not ControlFlowGraphImpl:: succ ( _, n , _)
31+ or
32+ // reachable predecessor -> we are the first unreachable node.
33+ exists ( AstNode pred |
34+ ControlFlowGraphImpl:: succ ( pred , n , _) and
35+ not unreachable ( pred )
36+ )
37+ )
2838}
2939
3040/**
0 commit comments