@@ -12,19 +12,29 @@ import rust
12
12
import codeql.rust.controlflow.ControlFlowGraph
13
13
import codeql.rust.controlflow.internal.ControlFlowGraphImpl as ControlFlowGraphImpl
14
14
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
+
15
22
/**
16
23
* Holds if `n` is an AST node that's unreachable, and is not the successor
17
24
* of an unreachable node (which would be a duplicate result).
18
25
*/
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
+ )
28
38
}
29
39
30
40
/**
0 commit comments