Rust: Remove spurious CFG edges in match expressions

This commit is contained in:
Tom Hvitved
2024-09-24 13:09:33 +02:00
parent 3b753da74e
commit 5f3663018e
3 changed files with 29 additions and 12 deletions

View File

@@ -356,24 +356,27 @@ class MatchArmTree extends ControlFlowTree instanceof MatchArm {
class MatchExprTree extends PostOrderTree instanceof MatchExpr {
override predicate propagatesAbnormal(AstNode child) {
child = [super.getExpr(), super.getMatchArmList().getAnArm().getExpr()]
child = [super.getExpr(), super.getAnArm().getExpr()]
}
override predicate first(AstNode node) { first(super.getExpr(), node) }
override predicate succ(AstNode pred, AstNode succ, Completion c) {
// Edge from the scrutinee to the first arm.
last(super.getExpr(), pred, c) and succ = super.getMatchArmList().getArm(0).getPat()
last(super.getExpr(), pred, c) and succ = super.getArm(0).getPat()
or
// Edge from a failed match/guard in one arm to the beginning of the next arm.
exists(int i |
last(super.getMatchArmList().getArm(i), pred, c) and
first(super.getMatchArmList().getArm(i + 1), succ) and
last(super.getArm(i), pred, c) and
first(super.getArm(i + 1), succ) and
c.(ConditionalCompletion).failed()
)
or
// Edge from the end of each arm to the match expression.
last(super.getMatchArmList().getArm(_), pred, c) and succ = this and completionIsNormal(c)
last(super.getArm(_).getExpr(), pred, c) and succ = this and completionIsNormal(c)
or
// Edge from the end of last arm to the match expression.
last(super.getLastArm().getExpr(), pred, c) and succ = this and completionIsNormal(c)
}
}

View File

@@ -1,4 +1,3 @@
// generated by codegen, remove this comment if you wish to edit this file
/**
* This module provides a hand-modifiable wrapper around the generated class `MatchExpr`.
*
@@ -27,5 +26,25 @@ module Impl {
* }
* ```
*/
class MatchExpr extends Generated::MatchExpr { }
class MatchExpr extends Generated::MatchExpr {
/**
* Gets the `index`th arm of this match expression.
*/
MatchArm getArm(int index) { result = this.getMatchArmList().getArm(index) }
/**
* Gets any of the arms of this match expression.
*/
MatchArm getAnArm() { result = this.getArm(_) }
/**
* Gets the number of arms of this match expression.
*/
int getNumberOfArms() { result = count(int i | exists(this.getArm(i))) }
/**
* Gets the last arm of this match expression.
*/
MatchArm getLastArm() { result = this.getArm(this.getNumberOfArms() - 1) }
}
}

View File

@@ -181,11 +181,9 @@
| test.rs:94:12:94:46 | ParenExpr | test.rs:97:13:97:13 | LiteralExpr | false |
| test.rs:94:13:94:45 | MatchExpr | test.rs:94:12:94:46 | ParenExpr | |
| test.rs:94:19:94:19 | PathExpr | test.rs:94:23:94:23 | LiteralPat | |
| test.rs:94:23:94:23 | LiteralPat | test.rs:94:13:94:45 | MatchExpr | no-match |
| test.rs:94:23:94:23 | LiteralPat | test.rs:94:28:94:31 | LiteralExpr | match |
| test.rs:94:23:94:23 | LiteralPat | test.rs:94:34:94:34 | WildcardPat | no-match |
| test.rs:94:28:94:31 | LiteralExpr | test.rs:94:13:94:45 | MatchExpr | |
| test.rs:94:34:94:34 | WildcardPat | test.rs:94:13:94:45 | MatchExpr | no-match |
| test.rs:94:34:94:34 | WildcardPat | test.rs:94:39:94:43 | LiteralExpr | match |
| test.rs:94:39:94:43 | LiteralExpr | test.rs:94:13:94:45 | MatchExpr | |
| test.rs:94:48:96:9 | BlockExpr | test.rs:94:9:98:9 | IfExpr | |
@@ -239,16 +237,13 @@
| test.rs:122:44:128:1 | BlockExpr | test.rs:122:1:128:1 | exit test_match (normal) | |
| test.rs:123:5:127:5 | MatchExpr | test.rs:122:44:128:1 | BlockExpr | |
| test.rs:123:11:123:21 | PathExpr | test.rs:124:9:124:23 | TupleStructPat | |
| test.rs:124:9:124:23 | TupleStructPat | test.rs:123:5:127:5 | MatchExpr | no-match |
| test.rs:124:9:124:23 | TupleStructPat | test.rs:124:28:124:28 | PathExpr | match |
| test.rs:124:9:124:23 | TupleStructPat | test.rs:125:9:125:23 | TupleStructPat | no-match |
| test.rs:124:28:124:28 | PathExpr | test.rs:124:32:124:33 | LiteralExpr | |
| test.rs:124:32:124:33 | LiteralExpr | test.rs:124:28:124:33 | BinaryExpr | |
| test.rs:125:9:125:23 | TupleStructPat | test.rs:123:5:127:5 | MatchExpr | no-match |
| test.rs:125:9:125:23 | TupleStructPat | test.rs:125:28:125:28 | PathExpr | match |
| test.rs:125:9:125:23 | TupleStructPat | test.rs:126:9:126:20 | PathPat | no-match |
| test.rs:125:28:125:28 | PathExpr | test.rs:123:5:127:5 | MatchExpr | |
| test.rs:126:9:126:20 | PathPat | test.rs:123:5:127:5 | MatchExpr | no-match |
| test.rs:126:9:126:20 | PathPat | test.rs:126:25:126:25 | LiteralExpr | match |
| test.rs:126:25:126:25 | LiteralExpr | test.rs:123:5:127:5 | MatchExpr | |
| test.rs:131:5:136:5 | enter test_infinite_loop | test.rs:132:9:134:9 | ExprStmt | |