Merge pull request #1986 from calumgrant/cs/switch-cfg

C#: Fix CFG for switch statements where the default case is not the last
This commit is contained in:
Tom Hvitved 2019-10-04 16:54:04 +02:00 коммит произвёл GitHub
Родитель 0e478d1c0e 28c34ad41e
Коммит b55e2948be
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
14 изменённых файлов: 331 добавлений и 13 удалений

Просмотреть файл

@ -39,5 +39,6 @@ The following changes in version 1.23 affect C# analysis in all applications.
disabled by default and can be enabled for individual configurations by
overriding `int explorationLimit()`.
* `foreach` statements where the body is guaranteed to be executed at least once, such as `foreach (var x in new string[]{ "a", "b", "c" }) { ... }`, are now recognized by all analyses based on the control flow graph (such as SSA, data flow and taint tracking).
* Fixed the control flow graph for `switch` statements where the `default` case was not the last case. This had caused the remaining cases to be unreachable. `SwitchStmt.getCase(int i)` now puts the `default` case last.
## Changes to autobuilder

Просмотреть файл

@ -165,6 +165,7 @@ class SwitchStmt extends SelectionStmt, Switch, @switch_stmt {
* return 3;
* }
* ```
* Note that this reorders the `default` case to always be at the end.
*/
override CaseStmt getCase(int i) { result = SwithStmtInternal::getCase(this, i) }
@ -215,9 +216,18 @@ private module SwithStmtInternal {
cached
CaseStmt getCase(SwitchStmt ss, int i) {
exists(int index, int rankIndex |
result = ss.getChildStmt(index) and
caseIndex(ss, result, index) and
rankIndex = i + 1 and
index = rank[rankIndex](int j, CaseStmt cs | cs = ss.getChildStmt(j) | j)
index = rank[rankIndex](int j, CaseStmt cs | caseIndex(ss, cs, j) | j)
)
}
/** Implicitly reorder case statements to put the default case last if needed. */
private predicate caseIndex(SwitchStmt ss, CaseStmt case, int index) {
exists(int i | case = ss.getChildStmt(i) |
if case instanceof DefaultCase
then index = max(int j | exists(ss.getChildStmt(j))) + 1
else index = i
)
}

Просмотреть файл

@ -741,7 +741,6 @@ module ControlFlow {
TLastRecBooleanNegationCompletion() or
TLastRecNonBooleanCompletion() or
TLastRecBreakCompletion() or
TLastRecNonBreakCompletion() or
TLastRecSwitchAbnormalCompletion() or
TLastRecInvalidOperationException() or
TLastRecNonContinueCompletion() or
@ -947,12 +946,6 @@ module ControlFlow {
result = cs.getCondition() and
c = specificBoolean(false)
)
or
// Last statement exits with any non-break completion
exists(int last | last = max(int i | exists(ss.getStmt(i))) |
result = ss.getStmt(last) and
c = TRec(TLastRecNonBreakCompletion())
)
)
or
cfe = any(SwitchExpr se |
@ -1156,10 +1149,6 @@ module ControlFlow {
c0 instanceof BreakCompletion and
c instanceof BreakNormalCompletion
or
rec = TLastRecNonBreakCompletion() and
not c0 instanceof BreakCompletion and
c = c0
or
rec = TLastRecSwitchAbnormalCompletion() and
not c instanceof BreakCompletion and
not c instanceof NormalCompletion and

Просмотреть файл

@ -555,6 +555,18 @@
| Switch.cs:131:40:131:40 | access to local variable s | Switch.cs:131:40:131:40 | access to local variable s | 1 |
| Switch.cs:131:43:131:51 | ... => ... | Switch.cs:131:48:131:51 | null | 3 |
| Switch.cs:131:56:131:66 | call to method ToString | Switch.cs:131:56:131:66 | call to method ToString | 1 |
| Switch.cs:134:9:134:11 | enter M13 | Switch.cs:139:18:139:18 | 1 | 6 |
| Switch.cs:134:9:134:11 | exit M13 | Switch.cs:134:9:134:11 | exit M13 | 1 |
| Switch.cs:138:13:138:20 | default: | Switch.cs:138:22:138:31 | return ...; | 4 |
| Switch.cs:139:28:139:28 | 1 | Switch.cs:139:21:139:29 | return ...; | 2 |
| Switch.cs:140:13:140:19 | case ...: | Switch.cs:140:18:140:18 | 2 | 2 |
| Switch.cs:140:28:140:28 | 2 | Switch.cs:140:21:140:29 | return ...; | 2 |
| Switch.cs:144:9:144:11 | enter M14 | Switch.cs:148:18:148:18 | 1 | 6 |
| Switch.cs:144:9:144:11 | exit M14 | Switch.cs:144:9:144:11 | exit M14 | 1 |
| Switch.cs:148:28:148:28 | 1 | Switch.cs:148:21:148:29 | return ...; | 2 |
| Switch.cs:149:13:149:20 | default: | Switch.cs:149:22:149:31 | return ...; | 4 |
| Switch.cs:150:13:150:19 | case ...: | Switch.cs:150:18:150:18 | 2 | 2 |
| Switch.cs:150:28:150:28 | 2 | Switch.cs:150:21:150:29 | return ...; | 2 |
| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:7:13:7:22 | ... is ... | 14 |
| TypeAccesses.cs:7:25:7:25 | ; | TypeAccesses.cs:7:25:7:25 | ; | 1 |
| TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:3:10:3:10 | exit M | 4 |

Просмотреть файл

@ -603,6 +603,18 @@ conditionBlock
| Switch.cs:129:12:129:14 | enter M12 | Switch.cs:131:43:131:51 | ... => ... | false |
| Switch.cs:129:12:129:14 | enter M12 | Switch.cs:131:56:131:66 | call to method ToString | true |
| Switch.cs:131:40:131:40 | access to local variable s | Switch.cs:131:56:131:66 | call to method ToString | false |
| Switch.cs:134:9:134:11 | enter M13 | Switch.cs:138:13:138:20 | default: | false |
| Switch.cs:134:9:134:11 | enter M13 | Switch.cs:139:28:139:28 | 1 | true |
| Switch.cs:134:9:134:11 | enter M13 | Switch.cs:140:13:140:19 | case ...: | false |
| Switch.cs:134:9:134:11 | enter M13 | Switch.cs:140:28:140:28 | 2 | false |
| Switch.cs:140:13:140:19 | case ...: | Switch.cs:138:13:138:20 | default: | false |
| Switch.cs:140:13:140:19 | case ...: | Switch.cs:140:28:140:28 | 2 | true |
| Switch.cs:144:9:144:11 | enter M14 | Switch.cs:148:28:148:28 | 1 | true |
| Switch.cs:144:9:144:11 | enter M14 | Switch.cs:149:13:149:20 | default: | false |
| Switch.cs:144:9:144:11 | enter M14 | Switch.cs:150:13:150:19 | case ...: | false |
| Switch.cs:144:9:144:11 | enter M14 | Switch.cs:150:28:150:28 | 2 | false |
| Switch.cs:150:13:150:19 | case ...: | Switch.cs:149:13:149:20 | default: | false |
| Switch.cs:150:13:150:19 | case ...: | Switch.cs:150:28:150:28 | 2 | true |
| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:7:25:7:25 | ; | true |
| VarDecls.cs:19:7:19:8 | enter M3 | VarDecls.cs:25:24:25:24 | access to local variable x | true |
| VarDecls.cs:19:7:19:8 | enter M3 | VarDecls.cs:25:28:25:28 | access to local variable y | false |

Просмотреть файл

@ -4,3 +4,4 @@ breakInvariant2
breakInvariant3
breakInvariant4
breakInvariant5
multipleSuccessors

Просмотреть файл

@ -94,3 +94,10 @@ query predicate breakInvariant5(
not (split.hasSuccessor(pred, succ, c) and split = predSplits.getASplit()) and
not (split.hasEntry(pred, succ, c) and not split = predSplits.getASplit())
}
query predicate multipleSuccessors(
ControlFlow::Node node, SuccessorType t, ControlFlow::Node successor
) {
strictcount(node.getASuccessorByType(t)) > 1 and
successor = node.getASuccessorByType(t)
}

Просмотреть файл

@ -2249,6 +2249,36 @@ dominance
| Switch.cs:131:40:131:40 | access to local variable s | Switch.cs:131:56:131:66 | call to method ToString |
| Switch.cs:131:43:131:43 | _ | Switch.cs:131:48:131:51 | null |
| Switch.cs:131:43:131:51 | ... => ... | Switch.cs:131:43:131:43 | _ |
| Switch.cs:134:9:134:11 | enter M13 | Switch.cs:135:5:142:5 | {...} |
| Switch.cs:135:5:142:5 | {...} | Switch.cs:136:9:141:9 | switch (...) {...} |
| Switch.cs:136:9:141:9 | switch (...) {...} | Switch.cs:136:17:136:17 | access to parameter i |
| Switch.cs:136:17:136:17 | access to parameter i | Switch.cs:139:13:139:19 | case ...: |
| Switch.cs:138:13:138:20 | default: | Switch.cs:138:30:138:30 | 1 |
| Switch.cs:138:29:138:30 | -... | Switch.cs:138:22:138:31 | return ...; |
| Switch.cs:138:30:138:30 | 1 | Switch.cs:138:29:138:30 | -... |
| Switch.cs:139:13:139:19 | case ...: | Switch.cs:139:18:139:18 | 1 |
| Switch.cs:139:18:139:18 | 1 | Switch.cs:139:28:139:28 | 1 |
| Switch.cs:139:18:139:18 | 1 | Switch.cs:140:13:140:19 | case ...: |
| Switch.cs:139:28:139:28 | 1 | Switch.cs:139:21:139:29 | return ...; |
| Switch.cs:140:13:140:19 | case ...: | Switch.cs:140:18:140:18 | 2 |
| Switch.cs:140:18:140:18 | 2 | Switch.cs:138:13:138:20 | default: |
| Switch.cs:140:18:140:18 | 2 | Switch.cs:140:28:140:28 | 2 |
| Switch.cs:140:28:140:28 | 2 | Switch.cs:140:21:140:29 | return ...; |
| Switch.cs:144:9:144:11 | enter M14 | Switch.cs:145:5:152:5 | {...} |
| Switch.cs:145:5:152:5 | {...} | Switch.cs:146:9:151:9 | switch (...) {...} |
| Switch.cs:146:9:151:9 | switch (...) {...} | Switch.cs:146:17:146:17 | access to parameter i |
| Switch.cs:146:17:146:17 | access to parameter i | Switch.cs:148:13:148:19 | case ...: |
| Switch.cs:148:13:148:19 | case ...: | Switch.cs:148:18:148:18 | 1 |
| Switch.cs:148:18:148:18 | 1 | Switch.cs:148:28:148:28 | 1 |
| Switch.cs:148:18:148:18 | 1 | Switch.cs:150:13:150:19 | case ...: |
| Switch.cs:148:28:148:28 | 1 | Switch.cs:148:21:148:29 | return ...; |
| Switch.cs:149:13:149:20 | default: | Switch.cs:149:30:149:30 | 1 |
| Switch.cs:149:29:149:30 | -... | Switch.cs:149:22:149:31 | return ...; |
| Switch.cs:149:30:149:30 | 1 | Switch.cs:149:29:149:30 | -... |
| Switch.cs:150:13:150:19 | case ...: | Switch.cs:150:18:150:18 | 2 |
| Switch.cs:150:18:150:18 | 2 | Switch.cs:149:13:149:20 | default: |
| Switch.cs:150:18:150:18 | 2 | Switch.cs:150:28:150:28 | 2 |
| Switch.cs:150:28:150:28 | 2 | Switch.cs:150:21:150:29 | return ...; |
| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:4:5:9:5 | {...} |
| TypeAccesses.cs:4:5:9:5 | {...} | TypeAccesses.cs:5:9:5:26 | ... ...; |
| TypeAccesses.cs:5:9:5:26 | ... ...; | TypeAccesses.cs:5:25:5:25 | access to parameter o |
@ -5092,6 +5122,34 @@ postDominance
| Switch.cs:131:28:131:40 | ... => ... | Switch.cs:131:17:131:17 | access to parameter o |
| Switch.cs:131:43:131:43 | _ | Switch.cs:131:43:131:51 | ... => ... |
| Switch.cs:131:48:131:51 | null | Switch.cs:131:43:131:43 | _ |
| Switch.cs:134:9:134:11 | exit M13 | Switch.cs:138:22:138:31 | return ...; |
| Switch.cs:134:9:134:11 | exit M13 | Switch.cs:139:21:139:29 | return ...; |
| Switch.cs:134:9:134:11 | exit M13 | Switch.cs:140:21:140:29 | return ...; |
| Switch.cs:135:5:142:5 | {...} | Switch.cs:134:9:134:11 | enter M13 |
| Switch.cs:136:9:141:9 | switch (...) {...} | Switch.cs:135:5:142:5 | {...} |
| Switch.cs:136:17:136:17 | access to parameter i | Switch.cs:136:9:141:9 | switch (...) {...} |
| Switch.cs:138:22:138:31 | return ...; | Switch.cs:138:29:138:30 | -... |
| Switch.cs:138:29:138:30 | -... | Switch.cs:138:30:138:30 | 1 |
| Switch.cs:138:30:138:30 | 1 | Switch.cs:138:13:138:20 | default: |
| Switch.cs:139:13:139:19 | case ...: | Switch.cs:136:17:136:17 | access to parameter i |
| Switch.cs:139:18:139:18 | 1 | Switch.cs:139:13:139:19 | case ...: |
| Switch.cs:139:21:139:29 | return ...; | Switch.cs:139:28:139:28 | 1 |
| Switch.cs:140:18:140:18 | 2 | Switch.cs:140:13:140:19 | case ...: |
| Switch.cs:140:21:140:29 | return ...; | Switch.cs:140:28:140:28 | 2 |
| Switch.cs:144:9:144:11 | exit M14 | Switch.cs:148:21:148:29 | return ...; |
| Switch.cs:144:9:144:11 | exit M14 | Switch.cs:149:22:149:31 | return ...; |
| Switch.cs:144:9:144:11 | exit M14 | Switch.cs:150:21:150:29 | return ...; |
| Switch.cs:145:5:152:5 | {...} | Switch.cs:144:9:144:11 | enter M14 |
| Switch.cs:146:9:151:9 | switch (...) {...} | Switch.cs:145:5:152:5 | {...} |
| Switch.cs:146:17:146:17 | access to parameter i | Switch.cs:146:9:151:9 | switch (...) {...} |
| Switch.cs:148:13:148:19 | case ...: | Switch.cs:146:17:146:17 | access to parameter i |
| Switch.cs:148:18:148:18 | 1 | Switch.cs:148:13:148:19 | case ...: |
| Switch.cs:148:21:148:29 | return ...; | Switch.cs:148:28:148:28 | 1 |
| Switch.cs:149:22:149:31 | return ...; | Switch.cs:149:29:149:30 | -... |
| Switch.cs:149:29:149:30 | -... | Switch.cs:149:30:149:30 | 1 |
| Switch.cs:149:30:149:30 | 1 | Switch.cs:149:13:149:20 | default: |
| Switch.cs:150:18:150:18 | 2 | Switch.cs:150:13:150:19 | case ...: |
| Switch.cs:150:21:150:29 | return ...; | Switch.cs:150:28:150:28 | 2 |
| TypeAccesses.cs:3:10:3:10 | exit M | TypeAccesses.cs:8:13:8:27 | Type t = ... |
| TypeAccesses.cs:4:5:9:5 | {...} | TypeAccesses.cs:3:10:3:10 | enter M |
| TypeAccesses.cs:5:9:5:26 | ... ...; | TypeAccesses.cs:4:5:9:5 | {...} |
@ -7350,6 +7408,32 @@ blockDominance
| Switch.cs:131:40:131:40 | access to local variable s | Switch.cs:131:56:131:66 | call to method ToString |
| Switch.cs:131:43:131:51 | ... => ... | Switch.cs:131:43:131:51 | ... => ... |
| Switch.cs:131:56:131:66 | call to method ToString | Switch.cs:131:56:131:66 | call to method ToString |
| Switch.cs:134:9:134:11 | enter M13 | Switch.cs:134:9:134:11 | enter M13 |
| Switch.cs:134:9:134:11 | enter M13 | Switch.cs:134:9:134:11 | exit M13 |
| Switch.cs:134:9:134:11 | enter M13 | Switch.cs:138:13:138:20 | default: |
| Switch.cs:134:9:134:11 | enter M13 | Switch.cs:139:28:139:28 | 1 |
| Switch.cs:134:9:134:11 | enter M13 | Switch.cs:140:13:140:19 | case ...: |
| Switch.cs:134:9:134:11 | enter M13 | Switch.cs:140:28:140:28 | 2 |
| Switch.cs:134:9:134:11 | exit M13 | Switch.cs:134:9:134:11 | exit M13 |
| Switch.cs:138:13:138:20 | default: | Switch.cs:138:13:138:20 | default: |
| Switch.cs:139:28:139:28 | 1 | Switch.cs:139:28:139:28 | 1 |
| Switch.cs:140:13:140:19 | case ...: | Switch.cs:138:13:138:20 | default: |
| Switch.cs:140:13:140:19 | case ...: | Switch.cs:140:13:140:19 | case ...: |
| Switch.cs:140:13:140:19 | case ...: | Switch.cs:140:28:140:28 | 2 |
| Switch.cs:140:28:140:28 | 2 | Switch.cs:140:28:140:28 | 2 |
| Switch.cs:144:9:144:11 | enter M14 | Switch.cs:144:9:144:11 | enter M14 |
| Switch.cs:144:9:144:11 | enter M14 | Switch.cs:144:9:144:11 | exit M14 |
| Switch.cs:144:9:144:11 | enter M14 | Switch.cs:148:28:148:28 | 1 |
| Switch.cs:144:9:144:11 | enter M14 | Switch.cs:149:13:149:20 | default: |
| Switch.cs:144:9:144:11 | enter M14 | Switch.cs:150:13:150:19 | case ...: |
| Switch.cs:144:9:144:11 | enter M14 | Switch.cs:150:28:150:28 | 2 |
| Switch.cs:144:9:144:11 | exit M14 | Switch.cs:144:9:144:11 | exit M14 |
| Switch.cs:148:28:148:28 | 1 | Switch.cs:148:28:148:28 | 1 |
| Switch.cs:149:13:149:20 | default: | Switch.cs:149:13:149:20 | default: |
| Switch.cs:150:13:150:19 | case ...: | Switch.cs:149:13:149:20 | default: |
| Switch.cs:150:13:150:19 | case ...: | Switch.cs:150:13:150:19 | case ...: |
| Switch.cs:150:13:150:19 | case ...: | Switch.cs:150:28:150:28 | 2 |
| Switch.cs:150:28:150:28 | 2 | Switch.cs:150:28:150:28 | 2 |
| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:3:10:3:10 | enter M |
| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:7:25:7:25 | ; |
| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:8:9:8:28 | ... ...; |
@ -9031,6 +9115,28 @@ postBlockDominance
| Switch.cs:131:40:131:40 | access to local variable s | Switch.cs:131:40:131:40 | access to local variable s |
| Switch.cs:131:43:131:51 | ... => ... | Switch.cs:131:43:131:51 | ... => ... |
| Switch.cs:131:56:131:66 | call to method ToString | Switch.cs:131:56:131:66 | call to method ToString |
| Switch.cs:134:9:134:11 | enter M13 | Switch.cs:134:9:134:11 | enter M13 |
| Switch.cs:134:9:134:11 | exit M13 | Switch.cs:134:9:134:11 | enter M13 |
| Switch.cs:134:9:134:11 | exit M13 | Switch.cs:134:9:134:11 | exit M13 |
| Switch.cs:134:9:134:11 | exit M13 | Switch.cs:138:13:138:20 | default: |
| Switch.cs:134:9:134:11 | exit M13 | Switch.cs:139:28:139:28 | 1 |
| Switch.cs:134:9:134:11 | exit M13 | Switch.cs:140:13:140:19 | case ...: |
| Switch.cs:134:9:134:11 | exit M13 | Switch.cs:140:28:140:28 | 2 |
| Switch.cs:138:13:138:20 | default: | Switch.cs:138:13:138:20 | default: |
| Switch.cs:139:28:139:28 | 1 | Switch.cs:139:28:139:28 | 1 |
| Switch.cs:140:13:140:19 | case ...: | Switch.cs:140:13:140:19 | case ...: |
| Switch.cs:140:28:140:28 | 2 | Switch.cs:140:28:140:28 | 2 |
| Switch.cs:144:9:144:11 | enter M14 | Switch.cs:144:9:144:11 | enter M14 |
| Switch.cs:144:9:144:11 | exit M14 | Switch.cs:144:9:144:11 | enter M14 |
| Switch.cs:144:9:144:11 | exit M14 | Switch.cs:144:9:144:11 | exit M14 |
| Switch.cs:144:9:144:11 | exit M14 | Switch.cs:148:28:148:28 | 1 |
| Switch.cs:144:9:144:11 | exit M14 | Switch.cs:149:13:149:20 | default: |
| Switch.cs:144:9:144:11 | exit M14 | Switch.cs:150:13:150:19 | case ...: |
| Switch.cs:144:9:144:11 | exit M14 | Switch.cs:150:28:150:28 | 2 |
| Switch.cs:148:28:148:28 | 1 | Switch.cs:148:28:148:28 | 1 |
| Switch.cs:149:13:149:20 | default: | Switch.cs:149:13:149:20 | default: |
| Switch.cs:150:13:150:19 | case ...: | Switch.cs:150:13:150:19 | case ...: |
| Switch.cs:150:28:150:28 | 2 | Switch.cs:150:28:150:28 | 2 |
| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:3:10:3:10 | enter M |
| TypeAccesses.cs:7:25:7:25 | ; | TypeAccesses.cs:7:25:7:25 | ; |
| TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:3:10:3:10 | enter M |

Просмотреть файл

@ -2432,6 +2432,40 @@ nodeEnclosing
| Switch.cs:131:43:131:51 | ... => ... | Switch.cs:129:12:129:14 | M12 |
| Switch.cs:131:48:131:51 | null | Switch.cs:129:12:129:14 | M12 |
| Switch.cs:131:56:131:66 | call to method ToString | Switch.cs:129:12:129:14 | M12 |
| Switch.cs:134:9:134:11 | enter M13 | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:134:9:134:11 | exit M13 | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:135:5:142:5 | {...} | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:136:9:141:9 | switch (...) {...} | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:136:17:136:17 | access to parameter i | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:138:13:138:20 | default: | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:138:22:138:31 | return ...; | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:138:29:138:30 | -... | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:138:30:138:30 | 1 | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:139:13:139:19 | case ...: | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:139:18:139:18 | 1 | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:139:21:139:29 | return ...; | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:139:28:139:28 | 1 | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:140:13:140:19 | case ...: | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:140:18:140:18 | 2 | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:140:21:140:29 | return ...; | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:140:28:140:28 | 2 | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:144:9:144:11 | enter M14 | Switch.cs:144:9:144:11 | M14 |
| Switch.cs:144:9:144:11 | exit M14 | Switch.cs:144:9:144:11 | M14 |
| Switch.cs:145:5:152:5 | {...} | Switch.cs:144:9:144:11 | M14 |
| Switch.cs:146:9:151:9 | switch (...) {...} | Switch.cs:144:9:144:11 | M14 |
| Switch.cs:146:17:146:17 | access to parameter i | Switch.cs:144:9:144:11 | M14 |
| Switch.cs:148:13:148:19 | case ...: | Switch.cs:144:9:144:11 | M14 |
| Switch.cs:148:18:148:18 | 1 | Switch.cs:144:9:144:11 | M14 |
| Switch.cs:148:21:148:29 | return ...; | Switch.cs:144:9:144:11 | M14 |
| Switch.cs:148:28:148:28 | 1 | Switch.cs:144:9:144:11 | M14 |
| Switch.cs:149:13:149:20 | default: | Switch.cs:144:9:144:11 | M14 |
| Switch.cs:149:22:149:31 | return ...; | Switch.cs:144:9:144:11 | M14 |
| Switch.cs:149:29:149:30 | -... | Switch.cs:144:9:144:11 | M14 |
| Switch.cs:149:30:149:30 | 1 | Switch.cs:144:9:144:11 | M14 |
| Switch.cs:150:13:150:19 | case ...: | Switch.cs:144:9:144:11 | M14 |
| Switch.cs:150:18:150:18 | 2 | Switch.cs:144:9:144:11 | M14 |
| Switch.cs:150:21:150:29 | return ...; | Switch.cs:144:9:144:11 | M14 |
| Switch.cs:150:28:150:28 | 2 | Switch.cs:144:9:144:11 | M14 |
| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:3:10:3:10 | M |
| TypeAccesses.cs:3:10:3:10 | exit M | TypeAccesses.cs:3:10:3:10 | M |
| TypeAccesses.cs:4:5:9:5 | {...} | TypeAccesses.cs:3:10:3:10 | M |
@ -3698,6 +3732,18 @@ blockEnclosing
| Switch.cs:131:40:131:40 | access to local variable s | Switch.cs:129:12:129:14 | M12 |
| Switch.cs:131:43:131:51 | ... => ... | Switch.cs:129:12:129:14 | M12 |
| Switch.cs:131:56:131:66 | call to method ToString | Switch.cs:129:12:129:14 | M12 |
| Switch.cs:134:9:134:11 | enter M13 | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:134:9:134:11 | exit M13 | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:138:13:138:20 | default: | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:139:28:139:28 | 1 | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:140:13:140:19 | case ...: | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:140:28:140:28 | 2 | Switch.cs:134:9:134:11 | M13 |
| Switch.cs:144:9:144:11 | enter M14 | Switch.cs:144:9:144:11 | M14 |
| Switch.cs:144:9:144:11 | exit M14 | Switch.cs:144:9:144:11 | M14 |
| Switch.cs:148:28:148:28 | 1 | Switch.cs:144:9:144:11 | M14 |
| Switch.cs:149:13:149:20 | default: | Switch.cs:144:9:144:11 | M14 |
| Switch.cs:150:13:150:19 | case ...: | Switch.cs:144:9:144:11 | M14 |
| Switch.cs:150:28:150:28 | 2 | Switch.cs:144:9:144:11 | M14 |
| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:3:10:3:10 | M |
| TypeAccesses.cs:7:25:7:25 | ; | TypeAccesses.cs:3:10:3:10 | M |
| TypeAccesses.cs:8:9:8:28 | ... ...; | TypeAccesses.cs:3:10:3:10 | M |

Просмотреть файл

@ -1756,6 +1756,36 @@
| Switch.cs:131:43:131:51 | ... => ... | Switch.cs:131:43:131:51 | ... => ... |
| Switch.cs:131:48:131:51 | null | Switch.cs:131:48:131:51 | null |
| Switch.cs:131:56:131:66 | call to method ToString | Switch.cs:131:17:131:53 | ... switch { ... } |
| Switch.cs:135:5:142:5 | {...} | Switch.cs:135:5:142:5 | {...} |
| Switch.cs:136:9:141:9 | switch (...) {...} | Switch.cs:136:9:141:9 | switch (...) {...} |
| Switch.cs:136:17:136:17 | access to parameter i | Switch.cs:136:17:136:17 | access to parameter i |
| Switch.cs:138:13:138:20 | default: | Switch.cs:138:13:138:20 | default: |
| Switch.cs:138:22:138:31 | return ...; | Switch.cs:138:30:138:30 | 1 |
| Switch.cs:138:29:138:30 | -... | Switch.cs:138:30:138:30 | 1 |
| Switch.cs:138:30:138:30 | 1 | Switch.cs:138:30:138:30 | 1 |
| Switch.cs:139:13:139:19 | case ...: | Switch.cs:139:13:139:19 | case ...: |
| Switch.cs:139:18:139:18 | 1 | Switch.cs:139:18:139:18 | 1 |
| Switch.cs:139:21:139:29 | return ...; | Switch.cs:139:28:139:28 | 1 |
| Switch.cs:139:28:139:28 | 1 | Switch.cs:139:28:139:28 | 1 |
| Switch.cs:140:13:140:19 | case ...: | Switch.cs:140:13:140:19 | case ...: |
| Switch.cs:140:18:140:18 | 2 | Switch.cs:140:18:140:18 | 2 |
| Switch.cs:140:21:140:29 | return ...; | Switch.cs:140:28:140:28 | 2 |
| Switch.cs:140:28:140:28 | 2 | Switch.cs:140:28:140:28 | 2 |
| Switch.cs:145:5:152:5 | {...} | Switch.cs:145:5:152:5 | {...} |
| Switch.cs:146:9:151:9 | switch (...) {...} | Switch.cs:146:9:151:9 | switch (...) {...} |
| Switch.cs:146:17:146:17 | access to parameter i | Switch.cs:146:17:146:17 | access to parameter i |
| Switch.cs:148:13:148:19 | case ...: | Switch.cs:148:13:148:19 | case ...: |
| Switch.cs:148:18:148:18 | 1 | Switch.cs:148:18:148:18 | 1 |
| Switch.cs:148:21:148:29 | return ...; | Switch.cs:148:28:148:28 | 1 |
| Switch.cs:148:28:148:28 | 1 | Switch.cs:148:28:148:28 | 1 |
| Switch.cs:149:13:149:20 | default: | Switch.cs:149:13:149:20 | default: |
| Switch.cs:149:22:149:31 | return ...; | Switch.cs:149:30:149:30 | 1 |
| Switch.cs:149:29:149:30 | -... | Switch.cs:149:30:149:30 | 1 |
| Switch.cs:149:30:149:30 | 1 | Switch.cs:149:30:149:30 | 1 |
| Switch.cs:150:13:150:19 | case ...: | Switch.cs:150:13:150:19 | case ...: |
| Switch.cs:150:18:150:18 | 2 | Switch.cs:150:18:150:18 | 2 |
| Switch.cs:150:21:150:29 | return ...; | Switch.cs:150:28:150:28 | 2 |
| Switch.cs:150:28:150:28 | 2 | Switch.cs:150:28:150:28 | 2 |
| TypeAccesses.cs:4:5:9:5 | {...} | TypeAccesses.cs:4:5:9:5 | {...} |
| TypeAccesses.cs:5:9:5:26 | ... ...; | TypeAccesses.cs:5:9:5:26 | ... ...; |
| TypeAccesses.cs:5:13:5:25 | String s = ... | TypeAccesses.cs:5:25:5:25 | access to parameter o |

Просмотреть файл

@ -2433,6 +2433,52 @@
| Switch.cs:131:56:131:66 | call to method ToString | Switch.cs:131:40:131:40 | access to local variable s | null |
| Switch.cs:131:56:131:66 | call to method ToString | Switch.cs:131:48:131:51 | null | null |
| Switch.cs:131:56:131:66 | call to method ToString | Switch.cs:131:56:131:66 | call to method ToString | normal |
| Switch.cs:135:5:142:5 | {...} | Switch.cs:138:22:138:31 | return ...; | return |
| Switch.cs:135:5:142:5 | {...} | Switch.cs:139:21:139:29 | return ...; | return |
| Switch.cs:135:5:142:5 | {...} | Switch.cs:140:21:140:29 | return ...; | return |
| Switch.cs:136:9:141:9 | switch (...) {...} | Switch.cs:138:22:138:31 | return ...; | return |
| Switch.cs:136:9:141:9 | switch (...) {...} | Switch.cs:139:21:139:29 | return ...; | return |
| Switch.cs:136:9:141:9 | switch (...) {...} | Switch.cs:140:21:140:29 | return ...; | return |
| Switch.cs:136:17:136:17 | access to parameter i | Switch.cs:136:17:136:17 | access to parameter i | normal |
| Switch.cs:138:13:138:20 | default: | Switch.cs:138:22:138:31 | return ...; | return |
| Switch.cs:138:22:138:31 | return ...; | Switch.cs:138:22:138:31 | return ...; | return |
| Switch.cs:138:29:138:30 | -... | Switch.cs:138:29:138:30 | -... | normal |
| Switch.cs:138:30:138:30 | 1 | Switch.cs:138:30:138:30 | 1 | normal |
| Switch.cs:139:13:139:19 | case ...: | Switch.cs:139:18:139:18 | 1 | no-match |
| Switch.cs:139:13:139:19 | case ...: | Switch.cs:139:21:139:29 | return ...; | return |
| Switch.cs:139:18:139:18 | 1 | Switch.cs:139:18:139:18 | 1 | match |
| Switch.cs:139:18:139:18 | 1 | Switch.cs:139:18:139:18 | 1 | no-match |
| Switch.cs:139:21:139:29 | return ...; | Switch.cs:139:21:139:29 | return ...; | return |
| Switch.cs:139:28:139:28 | 1 | Switch.cs:139:28:139:28 | 1 | normal |
| Switch.cs:140:13:140:19 | case ...: | Switch.cs:140:18:140:18 | 2 | no-match |
| Switch.cs:140:13:140:19 | case ...: | Switch.cs:140:21:140:29 | return ...; | return |
| Switch.cs:140:18:140:18 | 2 | Switch.cs:140:18:140:18 | 2 | match |
| Switch.cs:140:18:140:18 | 2 | Switch.cs:140:18:140:18 | 2 | no-match |
| Switch.cs:140:21:140:29 | return ...; | Switch.cs:140:21:140:29 | return ...; | return |
| Switch.cs:140:28:140:28 | 2 | Switch.cs:140:28:140:28 | 2 | normal |
| Switch.cs:145:5:152:5 | {...} | Switch.cs:148:21:148:29 | return ...; | return |
| Switch.cs:145:5:152:5 | {...} | Switch.cs:149:22:149:31 | return ...; | return |
| Switch.cs:145:5:152:5 | {...} | Switch.cs:150:21:150:29 | return ...; | return |
| Switch.cs:146:9:151:9 | switch (...) {...} | Switch.cs:148:21:148:29 | return ...; | return |
| Switch.cs:146:9:151:9 | switch (...) {...} | Switch.cs:149:22:149:31 | return ...; | return |
| Switch.cs:146:9:151:9 | switch (...) {...} | Switch.cs:150:21:150:29 | return ...; | return |
| Switch.cs:146:17:146:17 | access to parameter i | Switch.cs:146:17:146:17 | access to parameter i | normal |
| Switch.cs:148:13:148:19 | case ...: | Switch.cs:148:18:148:18 | 1 | no-match |
| Switch.cs:148:13:148:19 | case ...: | Switch.cs:148:21:148:29 | return ...; | return |
| Switch.cs:148:18:148:18 | 1 | Switch.cs:148:18:148:18 | 1 | match |
| Switch.cs:148:18:148:18 | 1 | Switch.cs:148:18:148:18 | 1 | no-match |
| Switch.cs:148:21:148:29 | return ...; | Switch.cs:148:21:148:29 | return ...; | return |
| Switch.cs:148:28:148:28 | 1 | Switch.cs:148:28:148:28 | 1 | normal |
| Switch.cs:149:13:149:20 | default: | Switch.cs:149:22:149:31 | return ...; | return |
| Switch.cs:149:22:149:31 | return ...; | Switch.cs:149:22:149:31 | return ...; | return |
| Switch.cs:149:29:149:30 | -... | Switch.cs:149:29:149:30 | -... | normal |
| Switch.cs:149:30:149:30 | 1 | Switch.cs:149:30:149:30 | 1 | normal |
| Switch.cs:150:13:150:19 | case ...: | Switch.cs:150:18:150:18 | 2 | no-match |
| Switch.cs:150:13:150:19 | case ...: | Switch.cs:150:21:150:29 | return ...; | return |
| Switch.cs:150:18:150:18 | 2 | Switch.cs:150:18:150:18 | 2 | match |
| Switch.cs:150:18:150:18 | 2 | Switch.cs:150:18:150:18 | 2 | no-match |
| Switch.cs:150:21:150:29 | return ...; | Switch.cs:150:21:150:29 | return ...; | return |
| Switch.cs:150:28:150:28 | 2 | Switch.cs:150:28:150:28 | 2 | normal |
| TypeAccesses.cs:4:5:9:5 | {...} | TypeAccesses.cs:8:13:8:27 | Type t = ... | normal |
| TypeAccesses.cs:5:9:5:26 | ... ...; | TypeAccesses.cs:5:13:5:25 | String s = ... | normal |
| TypeAccesses.cs:5:13:5:25 | String s = ... | TypeAccesses.cs:5:13:5:25 | String s = ... | normal |

Просмотреть файл

@ -2536,6 +2536,42 @@
| Switch.cs:131:43:131:51 | ... => ... | Switch.cs:131:43:131:43 | _ | semmle.label | successor |
| Switch.cs:131:48:131:51 | null | Switch.cs:131:9:131:67 | return ...; | semmle.label | null |
| Switch.cs:131:56:131:66 | call to method ToString | Switch.cs:131:9:131:67 | return ...; | semmle.label | successor |
| Switch.cs:134:9:134:11 | enter M13 | Switch.cs:135:5:142:5 | {...} | semmle.label | successor |
| Switch.cs:135:5:142:5 | {...} | Switch.cs:136:9:141:9 | switch (...) {...} | semmle.label | successor |
| Switch.cs:136:9:141:9 | switch (...) {...} | Switch.cs:136:17:136:17 | access to parameter i | semmle.label | successor |
| Switch.cs:136:17:136:17 | access to parameter i | Switch.cs:139:13:139:19 | case ...: | semmle.label | successor |
| Switch.cs:138:13:138:20 | default: | Switch.cs:138:30:138:30 | 1 | semmle.label | successor |
| Switch.cs:138:22:138:31 | return ...; | Switch.cs:134:9:134:11 | exit M13 | semmle.label | return |
| Switch.cs:138:29:138:30 | -... | Switch.cs:138:22:138:31 | return ...; | semmle.label | successor |
| Switch.cs:138:30:138:30 | 1 | Switch.cs:138:29:138:30 | -... | semmle.label | successor |
| Switch.cs:139:13:139:19 | case ...: | Switch.cs:139:18:139:18 | 1 | semmle.label | successor |
| Switch.cs:139:18:139:18 | 1 | Switch.cs:139:28:139:28 | 1 | semmle.label | match |
| Switch.cs:139:18:139:18 | 1 | Switch.cs:140:13:140:19 | case ...: | semmle.label | no-match |
| Switch.cs:139:21:139:29 | return ...; | Switch.cs:134:9:134:11 | exit M13 | semmle.label | return |
| Switch.cs:139:28:139:28 | 1 | Switch.cs:139:21:139:29 | return ...; | semmle.label | successor |
| Switch.cs:140:13:140:19 | case ...: | Switch.cs:140:18:140:18 | 2 | semmle.label | successor |
| Switch.cs:140:18:140:18 | 2 | Switch.cs:138:13:138:20 | default: | semmle.label | no-match |
| Switch.cs:140:18:140:18 | 2 | Switch.cs:140:28:140:28 | 2 | semmle.label | match |
| Switch.cs:140:21:140:29 | return ...; | Switch.cs:134:9:134:11 | exit M13 | semmle.label | return |
| Switch.cs:140:28:140:28 | 2 | Switch.cs:140:21:140:29 | return ...; | semmle.label | successor |
| Switch.cs:144:9:144:11 | enter M14 | Switch.cs:145:5:152:5 | {...} | semmle.label | successor |
| Switch.cs:145:5:152:5 | {...} | Switch.cs:146:9:151:9 | switch (...) {...} | semmle.label | successor |
| Switch.cs:146:9:151:9 | switch (...) {...} | Switch.cs:146:17:146:17 | access to parameter i | semmle.label | successor |
| Switch.cs:146:17:146:17 | access to parameter i | Switch.cs:148:13:148:19 | case ...: | semmle.label | successor |
| Switch.cs:148:13:148:19 | case ...: | Switch.cs:148:18:148:18 | 1 | semmle.label | successor |
| Switch.cs:148:18:148:18 | 1 | Switch.cs:148:28:148:28 | 1 | semmle.label | match |
| Switch.cs:148:18:148:18 | 1 | Switch.cs:150:13:150:19 | case ...: | semmle.label | no-match |
| Switch.cs:148:21:148:29 | return ...; | Switch.cs:144:9:144:11 | exit M14 | semmle.label | return |
| Switch.cs:148:28:148:28 | 1 | Switch.cs:148:21:148:29 | return ...; | semmle.label | successor |
| Switch.cs:149:13:149:20 | default: | Switch.cs:149:30:149:30 | 1 | semmle.label | successor |
| Switch.cs:149:22:149:31 | return ...; | Switch.cs:144:9:144:11 | exit M14 | semmle.label | return |
| Switch.cs:149:29:149:30 | -... | Switch.cs:149:22:149:31 | return ...; | semmle.label | successor |
| Switch.cs:149:30:149:30 | 1 | Switch.cs:149:29:149:30 | -... | semmle.label | successor |
| Switch.cs:150:13:150:19 | case ...: | Switch.cs:150:18:150:18 | 2 | semmle.label | successor |
| Switch.cs:150:18:150:18 | 2 | Switch.cs:149:13:149:20 | default: | semmle.label | no-match |
| Switch.cs:150:18:150:18 | 2 | Switch.cs:150:28:150:28 | 2 | semmle.label | match |
| Switch.cs:150:21:150:29 | return ...; | Switch.cs:144:9:144:11 | exit M14 | semmle.label | return |
| Switch.cs:150:28:150:28 | 2 | Switch.cs:150:21:150:29 | return ...; | semmle.label | successor |
| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:4:5:9:5 | {...} | semmle.label | successor |
| TypeAccesses.cs:4:5:9:5 | {...} | TypeAccesses.cs:5:9:5:26 | ... ...; | semmle.label | successor |
| TypeAccesses.cs:5:9:5:26 | ... ...; | TypeAccesses.cs:5:25:5:25 | access to parameter o | semmle.label | successor |

Просмотреть файл

@ -754,6 +754,8 @@ entryPoint
| Switch.cs:113:9:113:11 | M10 | Switch.cs:114:5:121:5 | {...} |
| Switch.cs:123:10:123:12 | M11 | Switch.cs:124:5:127:5 | {...} |
| Switch.cs:129:12:129:14 | M12 | Switch.cs:130:5:132:5 | {...} |
| Switch.cs:134:9:134:11 | M13 | Switch.cs:135:5:142:5 | {...} |
| Switch.cs:144:9:144:11 | M14 | Switch.cs:145:5:152:5 | {...} |
| TypeAccesses.cs:3:10:3:10 | M | TypeAccesses.cs:4:5:9:5 | {...} |
| VarDecls.cs:5:18:5:19 | M1 | VarDecls.cs:6:5:11:5 | {...} |
| VarDecls.cs:13:12:13:13 | M2 | VarDecls.cs:14:5:17:5 | {...} |

Просмотреть файл

@ -130,4 +130,24 @@ class Switch
{
return (o switch { string s => s, _ => null })?.ToString();
}
int M13(int i)
{
switch (i)
{
default: return -1;
case 1: return 1;
case 2: return 2;
}
}
int M14(int i)
{
switch (i)
{
case 1: return 1;
default: return -1;
case 2: return 2;
}
}
}