Merge branch 'main' into redsun82/update-rules-kotlin

This commit is contained in:
Paolo Tranquilli
2025-04-28 10:20:55 +02:00
19 changed files with 447 additions and 12 deletions

View File

@@ -278,9 +278,14 @@ class CaseStmt extends Case, @case_stmt {
override PatternExpr getPattern() { result = this.getChild(0) }
override Stmt getBody() {
exists(int i |
exists(int i, Stmt next |
this = this.getParent().getChild(i) and
result = this.getParent().getChild(i + 1)
next = this.getParent().getChild(i + 1)
|
result = next and
not result instanceof CaseStmt
or
result = next.(CaseStmt).getBody()
)
}

View File

@@ -1153,7 +1153,13 @@ module Statements {
)
or
// Flow from last element of `case` statement `i` to first element of statement `i+1`
exists(int i | last(super.getStmt(i).(CaseStmt).getBody(), pred, c) |
exists(int i, Stmt body |
body = super.getStmt(i).(CaseStmt).getBody() and
// in case of fall-through cases, make sure to not jump from their shared body back
// to one of the fall-through cases
not body = super.getStmt(i + 1).(CaseStmt).getBody() and
last(body, pred, c)
|
c instanceof NormalCompletion and
first(super.getStmt(i + 1), succ)
)

View File

@@ -1078,6 +1078,13 @@
| Switch.cs:156:50:156:52 | "b" | Switch.cs:156:41:156:52 | ... => ... | 2 |
| Switch.cs:158:13:158:49 | ...; | Switch.cs:158:13:158:48 | call to method WriteLine | 6 |
| Switch.cs:160:13:160:49 | ...; | Switch.cs:160:13:160:48 | call to method WriteLine | 6 |
| Switch.cs:163:10:163:12 | enter M16 | Switch.cs:167:18:167:18 | 1 | 6 |
| Switch.cs:163:10:163:12 | exit M16 (normal) | Switch.cs:163:10:163:12 | exit M16 | 2 |
| Switch.cs:168:13:168:19 | case ...: | Switch.cs:168:18:168:18 | 2 | 2 |
| Switch.cs:169:17:169:51 | ...; | Switch.cs:170:17:170:22 | break; | 4 |
| Switch.cs:171:13:171:19 | case ...: | Switch.cs:171:18:171:18 | 3 | 2 |
| Switch.cs:172:17:172:46 | ...; | Switch.cs:173:17:173:22 | break; | 4 |
| Switch.cs:174:13:174:20 | default: | Switch.cs:176:17:176:22 | break; | 5 |
| TypeAccesses.cs:1:7:1:18 | enter TypeAccesses | TypeAccesses.cs:1:7:1:18 | exit TypeAccesses | 5 |
| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:7:18:7:22 | Int32 j | 13 |
| TypeAccesses.cs:7:13:7:22 | [false] ... is ... | TypeAccesses.cs:7:13:7:22 | [false] ... is ... | 1 |

View File

@@ -2140,6 +2140,15 @@ conditionBlock
| Switch.cs:156:17:156:54 | ... switch { ... } | Switch.cs:158:13:158:49 | ...; | true |
| Switch.cs:156:17:156:54 | ... switch { ... } | Switch.cs:160:13:160:49 | ...; | false |
| Switch.cs:156:41:156:45 | false | Switch.cs:156:50:156:52 | "b" | true |
| Switch.cs:163:10:163:12 | enter M16 | Switch.cs:168:13:168:19 | case ...: | false |
| Switch.cs:163:10:163:12 | enter M16 | Switch.cs:171:13:171:19 | case ...: | false |
| Switch.cs:163:10:163:12 | enter M16 | Switch.cs:172:17:172:46 | ...; | false |
| Switch.cs:163:10:163:12 | enter M16 | Switch.cs:174:13:174:20 | default: | false |
| Switch.cs:168:13:168:19 | case ...: | Switch.cs:171:13:171:19 | case ...: | false |
| Switch.cs:168:13:168:19 | case ...: | Switch.cs:172:17:172:46 | ...; | false |
| Switch.cs:168:13:168:19 | case ...: | Switch.cs:174:13:174:20 | default: | false |
| Switch.cs:171:13:171:19 | case ...: | Switch.cs:172:17:172:46 | ...; | true |
| Switch.cs:171:13:171:19 | case ...: | Switch.cs:174:13:174:20 | default: | false |
| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:7:13:7:22 | [false] ... is ... | false |
| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:7:13:7:22 | [true] ... is ... | true |
| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:7:25:7:25 | ; | true |

View File

@@ -3678,6 +3678,29 @@ dominance
| Switch.cs:160:40:160:43 | "b = " | Switch.cs:160:45:160:45 | access to local variable s |
| Switch.cs:160:44:160:46 | {...} | Switch.cs:160:38:160:47 | $"..." |
| Switch.cs:160:45:160:45 | access to local variable s | Switch.cs:160:44:160:46 | {...} |
| Switch.cs:163:10:163:12 | enter M16 | Switch.cs:164:5:178:5 | {...} |
| Switch.cs:163:10:163:12 | exit M16 (normal) | Switch.cs:163:10:163:12 | exit M16 |
| Switch.cs:164:5:178:5 | {...} | Switch.cs:165:9:177:9 | switch (...) {...} |
| Switch.cs:165:9:177:9 | switch (...) {...} | Switch.cs:165:17:165:17 | access to parameter i |
| Switch.cs:165:17:165:17 | access to parameter i | Switch.cs:167:13:167:19 | case ...: |
| Switch.cs:167:13:167:19 | case ...: | Switch.cs:167:18:167:18 | 1 |
| Switch.cs:167:18:167:18 | 1 | Switch.cs:168:13:168:19 | case ...: |
| Switch.cs:167:18:167:18 | 1 | Switch.cs:169:17:169:51 | ...; |
| Switch.cs:168:13:168:19 | case ...: | Switch.cs:168:18:168:18 | 2 |
| Switch.cs:168:18:168:18 | 2 | Switch.cs:171:13:171:19 | case ...: |
| Switch.cs:169:17:169:50 | call to method WriteLine | Switch.cs:170:17:170:22 | break; |
| Switch.cs:169:17:169:51 | ...; | Switch.cs:169:42:169:49 | "1 or 2" |
| Switch.cs:169:42:169:49 | "1 or 2" | Switch.cs:169:17:169:50 | call to method WriteLine |
| Switch.cs:171:13:171:19 | case ...: | Switch.cs:171:18:171:18 | 3 |
| Switch.cs:171:18:171:18 | 3 | Switch.cs:172:17:172:46 | ...; |
| Switch.cs:171:18:171:18 | 3 | Switch.cs:174:13:174:20 | default: |
| Switch.cs:172:17:172:45 | call to method WriteLine | Switch.cs:173:17:173:22 | break; |
| Switch.cs:172:17:172:46 | ...; | Switch.cs:172:42:172:44 | "3" |
| Switch.cs:172:42:172:44 | "3" | Switch.cs:172:17:172:45 | call to method WriteLine |
| Switch.cs:174:13:174:20 | default: | Switch.cs:175:17:175:48 | ...; |
| Switch.cs:175:17:175:47 | call to method WriteLine | Switch.cs:176:17:176:22 | break; |
| Switch.cs:175:17:175:48 | ...; | Switch.cs:175:42:175:46 | "def" |
| Switch.cs:175:42:175:46 | "def" | Switch.cs:175:17:175:47 | call to method WriteLine |
| TypeAccesses.cs:1:7:1:18 | call to constructor Object | TypeAccesses.cs:1:7:1:18 | {...} |
| TypeAccesses.cs:1:7:1:18 | enter TypeAccesses | TypeAccesses.cs:1:7:1:18 | call to constructor Object |
| TypeAccesses.cs:1:7:1:18 | exit TypeAccesses (normal) | TypeAccesses.cs:1:7:1:18 | exit TypeAccesses |
@@ -7854,6 +7877,27 @@ postDominance
| Switch.cs:160:40:160:43 | "b = " | Switch.cs:160:13:160:49 | ...; |
| Switch.cs:160:44:160:46 | {...} | Switch.cs:160:45:160:45 | access to local variable s |
| Switch.cs:160:45:160:45 | access to local variable s | Switch.cs:160:40:160:43 | "b = " |
| Switch.cs:163:10:163:12 | exit M16 | Switch.cs:163:10:163:12 | exit M16 (normal) |
| Switch.cs:163:10:163:12 | exit M16 (normal) | Switch.cs:170:17:170:22 | break; |
| Switch.cs:163:10:163:12 | exit M16 (normal) | Switch.cs:173:17:173:22 | break; |
| Switch.cs:163:10:163:12 | exit M16 (normal) | Switch.cs:176:17:176:22 | break; |
| Switch.cs:164:5:178:5 | {...} | Switch.cs:163:10:163:12 | enter M16 |
| Switch.cs:165:9:177:9 | switch (...) {...} | Switch.cs:164:5:178:5 | {...} |
| Switch.cs:165:17:165:17 | access to parameter i | Switch.cs:165:9:177:9 | switch (...) {...} |
| Switch.cs:167:13:167:19 | case ...: | Switch.cs:165:17:165:17 | access to parameter i |
| Switch.cs:167:18:167:18 | 1 | Switch.cs:167:13:167:19 | case ...: |
| Switch.cs:168:18:168:18 | 2 | Switch.cs:168:13:168:19 | case ...: |
| Switch.cs:169:17:169:50 | call to method WriteLine | Switch.cs:169:42:169:49 | "1 or 2" |
| Switch.cs:169:42:169:49 | "1 or 2" | Switch.cs:169:17:169:51 | ...; |
| Switch.cs:170:17:170:22 | break; | Switch.cs:169:17:169:50 | call to method WriteLine |
| Switch.cs:171:18:171:18 | 3 | Switch.cs:171:13:171:19 | case ...: |
| Switch.cs:172:17:172:45 | call to method WriteLine | Switch.cs:172:42:172:44 | "3" |
| Switch.cs:172:42:172:44 | "3" | Switch.cs:172:17:172:46 | ...; |
| Switch.cs:173:17:173:22 | break; | Switch.cs:172:17:172:45 | call to method WriteLine |
| Switch.cs:175:17:175:47 | call to method WriteLine | Switch.cs:175:42:175:46 | "def" |
| Switch.cs:175:17:175:48 | ...; | Switch.cs:174:13:174:20 | default: |
| Switch.cs:175:42:175:46 | "def" | Switch.cs:175:17:175:48 | ...; |
| Switch.cs:176:17:176:22 | break; | Switch.cs:175:17:175:47 | call to method WriteLine |
| TypeAccesses.cs:1:7:1:18 | call to constructor Object | TypeAccesses.cs:1:7:1:18 | enter TypeAccesses |
| TypeAccesses.cs:1:7:1:18 | exit TypeAccesses | TypeAccesses.cs:1:7:1:18 | exit TypeAccesses (normal) |
| TypeAccesses.cs:1:7:1:18 | exit TypeAccesses (normal) | TypeAccesses.cs:1:7:1:18 | {...} |
@@ -12467,6 +12511,24 @@ blockDominance
| Switch.cs:156:50:156:52 | "b" | Switch.cs:156:50:156:52 | "b" |
| Switch.cs:158:13:158:49 | ...; | Switch.cs:158:13:158:49 | ...; |
| Switch.cs:160:13:160:49 | ...; | Switch.cs:160:13:160:49 | ...; |
| Switch.cs:163:10:163:12 | enter M16 | Switch.cs:163:10:163:12 | enter M16 |
| Switch.cs:163:10:163:12 | enter M16 | Switch.cs:163:10:163:12 | exit M16 (normal) |
| Switch.cs:163:10:163:12 | enter M16 | Switch.cs:168:13:168:19 | case ...: |
| Switch.cs:163:10:163:12 | enter M16 | Switch.cs:169:17:169:51 | ...; |
| Switch.cs:163:10:163:12 | enter M16 | Switch.cs:171:13:171:19 | case ...: |
| Switch.cs:163:10:163:12 | enter M16 | Switch.cs:172:17:172:46 | ...; |
| Switch.cs:163:10:163:12 | enter M16 | Switch.cs:174:13:174:20 | default: |
| Switch.cs:163:10:163:12 | exit M16 (normal) | Switch.cs:163:10:163:12 | exit M16 (normal) |
| Switch.cs:168:13:168:19 | case ...: | Switch.cs:168:13:168:19 | case ...: |
| Switch.cs:168:13:168:19 | case ...: | Switch.cs:171:13:171:19 | case ...: |
| Switch.cs:168:13:168:19 | case ...: | Switch.cs:172:17:172:46 | ...; |
| Switch.cs:168:13:168:19 | case ...: | Switch.cs:174:13:174:20 | default: |
| Switch.cs:169:17:169:51 | ...; | Switch.cs:169:17:169:51 | ...; |
| Switch.cs:171:13:171:19 | case ...: | Switch.cs:171:13:171:19 | case ...: |
| Switch.cs:171:13:171:19 | case ...: | Switch.cs:172:17:172:46 | ...; |
| Switch.cs:171:13:171:19 | case ...: | Switch.cs:174:13:174:20 | default: |
| Switch.cs:172:17:172:46 | ...; | Switch.cs:172:17:172:46 | ...; |
| Switch.cs:174:13:174:20 | default: | Switch.cs:174:13:174:20 | default: |
| TypeAccesses.cs:1:7:1:18 | enter TypeAccesses | TypeAccesses.cs:1:7:1:18 | enter TypeAccesses |
| 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:13:7:22 | [false] ... is ... |
@@ -15794,6 +15856,19 @@ postBlockDominance
| Switch.cs:156:50:156:52 | "b" | Switch.cs:156:50:156:52 | "b" |
| Switch.cs:158:13:158:49 | ...; | Switch.cs:158:13:158:49 | ...; |
| Switch.cs:160:13:160:49 | ...; | Switch.cs:160:13:160:49 | ...; |
| Switch.cs:163:10:163:12 | enter M16 | Switch.cs:163:10:163:12 | enter M16 |
| Switch.cs:163:10:163:12 | exit M16 (normal) | Switch.cs:163:10:163:12 | enter M16 |
| Switch.cs:163:10:163:12 | exit M16 (normal) | Switch.cs:163:10:163:12 | exit M16 (normal) |
| Switch.cs:163:10:163:12 | exit M16 (normal) | Switch.cs:168:13:168:19 | case ...: |
| Switch.cs:163:10:163:12 | exit M16 (normal) | Switch.cs:169:17:169:51 | ...; |
| Switch.cs:163:10:163:12 | exit M16 (normal) | Switch.cs:171:13:171:19 | case ...: |
| Switch.cs:163:10:163:12 | exit M16 (normal) | Switch.cs:172:17:172:46 | ...; |
| Switch.cs:163:10:163:12 | exit M16 (normal) | Switch.cs:174:13:174:20 | default: |
| Switch.cs:168:13:168:19 | case ...: | Switch.cs:168:13:168:19 | case ...: |
| Switch.cs:169:17:169:51 | ...; | Switch.cs:169:17:169:51 | ...; |
| Switch.cs:171:13:171:19 | case ...: | Switch.cs:171:13:171:19 | case ...: |
| Switch.cs:172:17:172:46 | ...; | Switch.cs:172:17:172:46 | ...; |
| Switch.cs:174:13:174:20 | default: | Switch.cs:174:13:174:20 | default: |
| TypeAccesses.cs:1:7:1:18 | enter TypeAccesses | TypeAccesses.cs:1:7:1:18 | enter TypeAccesses |
| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:3:10:3:10 | enter M |
| TypeAccesses.cs:7:13:7:22 | [false] ... is ... | TypeAccesses.cs:7:13:7:22 | [false] ... is ... |

View File

@@ -4029,6 +4029,31 @@ nodeEnclosing
| Switch.cs:160:40:160:43 | "b = " | Switch.cs:154:10:154:12 | M15 |
| Switch.cs:160:44:160:46 | {...} | Switch.cs:154:10:154:12 | M15 |
| Switch.cs:160:45:160:45 | access to local variable s | Switch.cs:154:10:154:12 | M15 |
| Switch.cs:163:10:163:12 | enter M16 | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:163:10:163:12 | exit M16 | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:163:10:163:12 | exit M16 (normal) | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:164:5:178:5 | {...} | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:165:9:177:9 | switch (...) {...} | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:165:17:165:17 | access to parameter i | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:167:13:167:19 | case ...: | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:167:18:167:18 | 1 | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:168:13:168:19 | case ...: | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:168:18:168:18 | 2 | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:169:17:169:50 | call to method WriteLine | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:169:17:169:51 | ...; | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:169:42:169:49 | "1 or 2" | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:170:17:170:22 | break; | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:171:13:171:19 | case ...: | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:171:18:171:18 | 3 | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:172:17:172:45 | call to method WriteLine | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:172:17:172:46 | ...; | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:172:42:172:44 | "3" | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:173:17:173:22 | break; | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:174:13:174:20 | default: | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:175:17:175:47 | call to method WriteLine | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:175:17:175:48 | ...; | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:175:42:175:46 | "def" | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:176:17:176:22 | break; | Switch.cs:163:10:163:12 | M16 |
| TypeAccesses.cs:1:7:1:18 | call to constructor Object | TypeAccesses.cs:1:7:1:18 | TypeAccesses |
| TypeAccesses.cs:1:7:1:18 | enter TypeAccesses | TypeAccesses.cs:1:7:1:18 | TypeAccesses |
| TypeAccesses.cs:1:7:1:18 | exit TypeAccesses | TypeAccesses.cs:1:7:1:18 | TypeAccesses |
@@ -5913,6 +5938,13 @@ blockEnclosing
| Switch.cs:156:50:156:52 | "b" | Switch.cs:154:10:154:12 | M15 |
| Switch.cs:158:13:158:49 | ...; | Switch.cs:154:10:154:12 | M15 |
| Switch.cs:160:13:160:49 | ...; | Switch.cs:154:10:154:12 | M15 |
| Switch.cs:163:10:163:12 | enter M16 | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:163:10:163:12 | exit M16 (normal) | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:168:13:168:19 | case ...: | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:169:17:169:51 | ...; | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:171:13:171:19 | case ...: | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:172:17:172:46 | ...; | Switch.cs:163:10:163:12 | M16 |
| Switch.cs:174:13:174:20 | default: | Switch.cs:163:10:163:12 | M16 |
| TypeAccesses.cs:1:7:1:18 | enter TypeAccesses | TypeAccesses.cs:1:7:1:18 | TypeAccesses |
| TypeAccesses.cs:3:10:3:10 | enter M | TypeAccesses.cs:3:10:3:10 | M |
| TypeAccesses.cs:7:13:7:22 | [false] ... is ... | TypeAccesses.cs:3:10:3:10 | M |

View File

@@ -2711,6 +2711,28 @@
| Switch.cs:160:40:160:43 | "b = " | Switch.cs:160:40:160:43 | "b = " |
| Switch.cs:160:44:160:46 | {...} | Switch.cs:160:45:160:45 | access to local variable s |
| Switch.cs:160:45:160:45 | access to local variable s | Switch.cs:160:45:160:45 | access to local variable s |
| Switch.cs:164:5:178:5 | {...} | Switch.cs:164:5:178:5 | {...} |
| Switch.cs:165:9:177:9 | switch (...) {...} | Switch.cs:165:9:177:9 | switch (...) {...} |
| Switch.cs:165:17:165:17 | access to parameter i | Switch.cs:165:17:165:17 | access to parameter i |
| Switch.cs:167:13:167:19 | case ...: | Switch.cs:167:13:167:19 | case ...: |
| Switch.cs:167:18:167:18 | 1 | Switch.cs:167:18:167:18 | 1 |
| Switch.cs:168:13:168:19 | case ...: | Switch.cs:168:13:168:19 | case ...: |
| Switch.cs:168:18:168:18 | 2 | Switch.cs:168:18:168:18 | 2 |
| Switch.cs:169:17:169:50 | call to method WriteLine | Switch.cs:169:42:169:49 | "1 or 2" |
| Switch.cs:169:17:169:51 | ...; | Switch.cs:169:17:169:51 | ...; |
| Switch.cs:169:42:169:49 | "1 or 2" | Switch.cs:169:42:169:49 | "1 or 2" |
| Switch.cs:170:17:170:22 | break; | Switch.cs:170:17:170:22 | break; |
| Switch.cs:171:13:171:19 | case ...: | Switch.cs:171:13:171:19 | case ...: |
| Switch.cs:171:18:171:18 | 3 | Switch.cs:171:18:171:18 | 3 |
| Switch.cs:172:17:172:45 | call to method WriteLine | Switch.cs:172:42:172:44 | "3" |
| Switch.cs:172:17:172:46 | ...; | Switch.cs:172:17:172:46 | ...; |
| Switch.cs:172:42:172:44 | "3" | Switch.cs:172:42:172:44 | "3" |
| Switch.cs:173:17:173:22 | break; | Switch.cs:173:17:173:22 | break; |
| Switch.cs:174:13:174:20 | default: | Switch.cs:174:13:174:20 | default: |
| Switch.cs:175:17:175:47 | call to method WriteLine | Switch.cs:175:42:175:46 | "def" |
| Switch.cs:175:17:175:48 | ...; | Switch.cs:175:17:175:48 | ...; |
| Switch.cs:175:42:175:46 | "def" | Switch.cs:175:42:175:46 | "def" |
| Switch.cs:176:17:176:22 | break; | Switch.cs:176:17:176:22 | break; |
| TypeAccesses.cs:1:7:1:18 | call to constructor Object | TypeAccesses.cs:1:7:1:18 | call to constructor Object |
| TypeAccesses.cs:1:7:1:18 | {...} | TypeAccesses.cs:1:7:1:18 | {...} |
| TypeAccesses.cs:4:5:9:5 | {...} | TypeAccesses.cs:4:5:9:5 | {...} |

View File

@@ -3581,6 +3581,38 @@
| Switch.cs:160:40:160:43 | "b = " | Switch.cs:160:40:160:43 | "b = " | normal |
| Switch.cs:160:44:160:46 | {...} | Switch.cs:160:44:160:46 | {...} | normal |
| Switch.cs:160:45:160:45 | access to local variable s | Switch.cs:160:45:160:45 | access to local variable s | normal |
| Switch.cs:164:5:178:5 | {...} | Switch.cs:170:17:170:22 | break; | normal [break] (0) |
| Switch.cs:164:5:178:5 | {...} | Switch.cs:173:17:173:22 | break; | normal [break] (0) |
| Switch.cs:164:5:178:5 | {...} | Switch.cs:176:17:176:22 | break; | normal [break] (0) |
| Switch.cs:165:9:177:9 | switch (...) {...} | Switch.cs:170:17:170:22 | break; | normal [break] (0) |
| Switch.cs:165:9:177:9 | switch (...) {...} | Switch.cs:173:17:173:22 | break; | normal [break] (0) |
| Switch.cs:165:9:177:9 | switch (...) {...} | Switch.cs:176:17:176:22 | break; | normal [break] (0) |
| Switch.cs:165:17:165:17 | access to parameter i | Switch.cs:165:17:165:17 | access to parameter i | normal |
| Switch.cs:167:13:167:19 | case ...: | Switch.cs:167:18:167:18 | 1 | no-match |
| Switch.cs:167:13:167:19 | case ...: | Switch.cs:169:17:169:50 | call to method WriteLine | normal |
| Switch.cs:167:18:167:18 | 1 | Switch.cs:167:18:167:18 | 1 | match |
| Switch.cs:167:18:167:18 | 1 | Switch.cs:167:18:167:18 | 1 | no-match |
| Switch.cs:168:13:168:19 | case ...: | Switch.cs:168:18:168:18 | 2 | no-match |
| Switch.cs:168:13:168:19 | case ...: | Switch.cs:169:17:169:50 | call to method WriteLine | normal |
| Switch.cs:168:18:168:18 | 2 | Switch.cs:168:18:168:18 | 2 | match |
| Switch.cs:168:18:168:18 | 2 | Switch.cs:168:18:168:18 | 2 | no-match |
| Switch.cs:169:17:169:50 | call to method WriteLine | Switch.cs:169:17:169:50 | call to method WriteLine | normal |
| Switch.cs:169:17:169:51 | ...; | Switch.cs:169:17:169:50 | call to method WriteLine | normal |
| Switch.cs:169:42:169:49 | "1 or 2" | Switch.cs:169:42:169:49 | "1 or 2" | normal |
| Switch.cs:170:17:170:22 | break; | Switch.cs:170:17:170:22 | break; | break |
| Switch.cs:171:13:171:19 | case ...: | Switch.cs:171:18:171:18 | 3 | no-match |
| Switch.cs:171:13:171:19 | case ...: | Switch.cs:172:17:172:45 | call to method WriteLine | normal |
| Switch.cs:171:18:171:18 | 3 | Switch.cs:171:18:171:18 | 3 | match |
| Switch.cs:171:18:171:18 | 3 | Switch.cs:171:18:171:18 | 3 | no-match |
| Switch.cs:172:17:172:45 | call to method WriteLine | Switch.cs:172:17:172:45 | call to method WriteLine | normal |
| Switch.cs:172:17:172:46 | ...; | Switch.cs:172:17:172:45 | call to method WriteLine | normal |
| Switch.cs:172:42:172:44 | "3" | Switch.cs:172:42:172:44 | "3" | normal |
| Switch.cs:173:17:173:22 | break; | Switch.cs:173:17:173:22 | break; | break |
| Switch.cs:174:13:174:20 | default: | Switch.cs:175:17:175:47 | call to method WriteLine | normal |
| Switch.cs:175:17:175:47 | call to method WriteLine | Switch.cs:175:17:175:47 | call to method WriteLine | normal |
| Switch.cs:175:17:175:48 | ...; | Switch.cs:175:17:175:47 | call to method WriteLine | normal |
| Switch.cs:175:42:175:46 | "def" | Switch.cs:175:42:175:46 | "def" | normal |
| Switch.cs:176:17:176:22 | break; | Switch.cs:176:17:176:22 | break; | break |
| TypeAccesses.cs:1:7:1:18 | call to constructor Object | TypeAccesses.cs:1:7:1:18 | call to constructor Object | normal |
| TypeAccesses.cs:1:7:1:18 | {...} | TypeAccesses.cs:1:7:1:18 | {...} | normal |
| TypeAccesses.cs:4:5:9:5 | {...} | TypeAccesses.cs:8:13:8:27 | Type t = ... | normal |

View File

@@ -4145,6 +4145,33 @@
| Switch.cs:160:40:160:43 | "b = " | Switch.cs:160:45:160:45 | access to local variable s | |
| Switch.cs:160:44:160:46 | {...} | Switch.cs:160:38:160:47 | $"..." | |
| Switch.cs:160:45:160:45 | access to local variable s | Switch.cs:160:44:160:46 | {...} | |
| Switch.cs:163:10:163:12 | enter M16 | Switch.cs:164:5:178:5 | {...} | |
| Switch.cs:163:10:163:12 | exit M16 (normal) | Switch.cs:163:10:163:12 | exit M16 | |
| Switch.cs:164:5:178:5 | {...} | Switch.cs:165:9:177:9 | switch (...) {...} | |
| Switch.cs:165:9:177:9 | switch (...) {...} | Switch.cs:165:17:165:17 | access to parameter i | |
| Switch.cs:165:17:165:17 | access to parameter i | Switch.cs:167:13:167:19 | case ...: | |
| Switch.cs:167:13:167:19 | case ...: | Switch.cs:167:18:167:18 | 1 | |
| Switch.cs:167:18:167:18 | 1 | Switch.cs:168:13:168:19 | case ...: | no-match |
| Switch.cs:167:18:167:18 | 1 | Switch.cs:169:17:169:51 | ...; | match |
| Switch.cs:168:13:168:19 | case ...: | Switch.cs:168:18:168:18 | 2 | |
| Switch.cs:168:18:168:18 | 2 | Switch.cs:169:17:169:51 | ...; | match |
| Switch.cs:168:18:168:18 | 2 | Switch.cs:171:13:171:19 | case ...: | no-match |
| Switch.cs:169:17:169:50 | call to method WriteLine | Switch.cs:170:17:170:22 | break; | |
| Switch.cs:169:17:169:51 | ...; | Switch.cs:169:42:169:49 | "1 or 2" | |
| Switch.cs:169:42:169:49 | "1 or 2" | Switch.cs:169:17:169:50 | call to method WriteLine | |
| Switch.cs:170:17:170:22 | break; | Switch.cs:163:10:163:12 | exit M16 (normal) | break |
| Switch.cs:171:13:171:19 | case ...: | Switch.cs:171:18:171:18 | 3 | |
| Switch.cs:171:18:171:18 | 3 | Switch.cs:172:17:172:46 | ...; | match |
| Switch.cs:171:18:171:18 | 3 | Switch.cs:174:13:174:20 | default: | no-match |
| Switch.cs:172:17:172:45 | call to method WriteLine | Switch.cs:173:17:173:22 | break; | |
| Switch.cs:172:17:172:46 | ...; | Switch.cs:172:42:172:44 | "3" | |
| Switch.cs:172:42:172:44 | "3" | Switch.cs:172:17:172:45 | call to method WriteLine | |
| Switch.cs:173:17:173:22 | break; | Switch.cs:163:10:163:12 | exit M16 (normal) | break |
| Switch.cs:174:13:174:20 | default: | Switch.cs:175:17:175:48 | ...; | |
| Switch.cs:175:17:175:47 | call to method WriteLine | Switch.cs:176:17:176:22 | break; | |
| Switch.cs:175:17:175:48 | ...; | Switch.cs:175:42:175:46 | "def" | |
| Switch.cs:175:42:175:46 | "def" | Switch.cs:175:17:175:47 | call to method WriteLine | |
| Switch.cs:176:17:176:22 | break; | Switch.cs:163:10:163:12 | exit M16 (normal) | break |
| TypeAccesses.cs:1:7:1:18 | call to constructor Object | TypeAccesses.cs:1:7:1:18 | {...} | |
| TypeAccesses.cs:1:7:1:18 | enter TypeAccesses | TypeAccesses.cs:1:7:1:18 | call to constructor Object | |
| TypeAccesses.cs:1:7:1:18 | exit TypeAccesses (normal) | TypeAccesses.cs:1:7:1:18 | exit TypeAccesses | |

View File

@@ -1256,6 +1256,7 @@ entryPoint
| 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 | {...} |
| Switch.cs:154:10:154:12 | M15 | Switch.cs:155:5:161:5 | {...} |
| Switch.cs:163:10:163:12 | M16 | Switch.cs:164:5:178:5 | {...} |
| TypeAccesses.cs:1:7:1:18 | TypeAccesses | TypeAccesses.cs:1:7:1:18 | call to constructor Object |
| TypeAccesses.cs:3:10:3:10 | M | TypeAccesses.cs:4:5:9:5 | {...} |
| VarDecls.cs:3:7:3:14 | VarDecls | VarDecls.cs:3:7:3:14 | call to constructor Object |

View File

@@ -159,4 +159,21 @@ class Switch
else
System.Console.WriteLine($"b = {s}");
}
void M16(int i)
{
switch (i)
{
case 1:
case 2:
System.Console.WriteLine("1 or 2");
break;
case 3:
System.Console.WriteLine("3");
break;
default:
System.Console.WriteLine("def");
break;
}
}
}

View File

@@ -67,13 +67,13 @@ func restoreRepoLayout(fromDir string, dirEntries []string, scratchDirName strin
// addVersionToMod add a go version directive, e.g. `go 1.14` to a `go.mod` file.
func addVersionToMod(version string) bool {
cmd := exec.Command("go", "mod", "edit", "-go="+version)
cmd := toolchain.GoCommand("mod", "edit", "-go="+version)
return util.RunCmd(cmd)
}
// checkVendor tests to see whether a vendor directory is inconsistent according to the go frontend
func checkVendor() bool {
vendorCheckCmd := exec.Command("go", "list", "-mod=vendor", "./...")
vendorCheckCmd := toolchain.GoCommand("list", "-mod=vendor", "./...")
outp, err := vendorCheckCmd.CombinedOutput()
if err != nil {
badVendorRe := regexp.MustCompile(`(?m)^go: inconsistent vendoring in .*:$`)
@@ -438,7 +438,7 @@ func installDependencies(workspace project.GoWorkspace) {
util.RunCmd(vendor)
}
install = exec.Command("go", "get", "-v", "./...")
install = toolchain.GoCommand("get", "-v", "./...")
install.Dir = path
log.Printf("Installing dependencies using `go get -v ./...` in `%s`.\n", path)
util.RunCmd(install)

View File

@@ -137,9 +137,16 @@ func SupportsWorkspaces() bool {
return GetEnvGoSemVer().IsAtLeast(V1_18)
}
// Constructs a `*exec.Cmd` for `go` with the specified arguments.
func GoCommand(arg ...string) *exec.Cmd {
cmd := exec.Command("go", arg...)
util.ApplyProxyEnvVars(cmd)
return cmd
}
// Run `go mod tidy -e` in the directory given by `path`.
func TidyModule(path string) *exec.Cmd {
cmd := exec.Command("go", "mod", "tidy", "-e")
cmd := GoCommand("mod", "tidy", "-e")
cmd.Dir = path
return cmd
}
@@ -159,21 +166,21 @@ func InitModule(path string) *exec.Cmd {
}
}
modInit := exec.Command("go", "mod", "init", moduleName)
modInit := GoCommand("mod", "init", moduleName)
modInit.Dir = path
return modInit
}
// Constructs a command to run `go mod vendor -e` in the directory given by `path`.
func VendorModule(path string) *exec.Cmd {
modVendor := exec.Command("go", "mod", "vendor", "-e")
modVendor := GoCommand("mod", "vendor", "-e")
modVendor.Dir = path
return modVendor
}
// Constructs a command to run `go version`.
func Version() *exec.Cmd {
version := exec.Command("go", "version")
version := GoCommand("version")
return version
}
@@ -209,7 +216,7 @@ func RunListWithEnv(format string, patterns []string, additionalEnv []string, fl
func ListWithEnv(format string, patterns []string, additionalEnv []string, flags ...string) *exec.Cmd {
args := append([]string{"list", "-e", "-f", format}, flags...)
args = append(args, patterns...)
cmd := exec.Command("go", args...)
cmd := GoCommand(args...)
cmd.Env = append(os.Environ(), additionalEnv...)
return cmd
}

View File

@@ -6,6 +6,7 @@ go_library(
name = "util",
srcs = [
"extractvendordirs.go",
"registryproxy.go",
"semver.go",
"util.go",
],
@@ -17,6 +18,7 @@ go_library(
go_test(
name = "util_test",
srcs = [
"registryproxy_test.go",
"semver_test.go",
"util_test.go",
],

View File

@@ -0,0 +1,134 @@
package util
import (
"encoding/json"
"fmt"
"log/slog"
"os"
"os/exec"
"strings"
)
const PROXY_HOST = "CODEQL_PROXY_HOST"
const PROXY_PORT = "CODEQL_PROXY_PORT"
const PROXY_CA_CERTIFICATE = "CODEQL_PROXY_CA_CERTIFICATE"
const PROXY_URLS = "CODEQL_PROXY_URLS"
const GOPROXY_SERVER = "goproxy_server"
type RegistryConfig struct {
Type string `json:"type"`
URL string `json:"url"`
}
// The address of the proxy including protocol and port (e.g. http://localhost:1234)
var proxy_address string
// The path to the temporary file that stores the proxy certificate, if any.
var proxy_cert_file string
// An array of registry configurations that are relevant to Go.
// This excludes other registry configurations that may be available, but are not relevant to Go.
var proxy_configs []RegistryConfig
// Stores the environment variables that we wish to pass on to `go` commands.
var proxy_vars []string = nil
// Keeps track of whether we have inspected the proxy environment variables.
// Needed since `proxy_vars` may be nil either way.
var proxy_vars_checked bool = false
// Tries to parse the given string value into an array of RegistryConfig values.
func parseRegistryConfigs(str string) ([]RegistryConfig, error) {
var configs []RegistryConfig
if err := json.Unmarshal([]byte(str), &configs); err != nil {
return nil, err
}
return configs, nil
}
func getEnvVars() []string {
var result []string
if proxy_host, proxy_host_set := os.LookupEnv(PROXY_HOST); proxy_host_set {
if proxy_port, proxy_port_set := os.LookupEnv(PROXY_PORT); proxy_port_set {
proxy_address = fmt.Sprintf("http://%s:%s", proxy_host, proxy_port)
result = append(result, fmt.Sprintf("HTTP_PROXY=%s", proxy_address), fmt.Sprintf("HTTPS_PROXY=%s", proxy_address))
slog.Info("Found private registry proxy", slog.String("proxy_address", proxy_address))
}
}
if proxy_cert, proxy_cert_set := os.LookupEnv(PROXY_CA_CERTIFICATE); proxy_cert_set {
// Write the certificate to a temporary file
slog.Info("Found certificate")
f, err := os.CreateTemp("", "codeql-proxy.crt")
if err != nil {
slog.Error("Failed to create temporary file for the proxy certificate", slog.String("error", err.Error()))
}
_, err = f.WriteString(proxy_cert)
if err != nil {
slog.Error("Failed to write to the temporary certificate file", slog.String("error", err.Error()))
}
err = f.Close()
if err != nil {
slog.Error("Failed to close the temporary certificate file", slog.String("error", err.Error()))
} else {
proxy_cert_file = f.Name()
result = append(result, fmt.Sprintf("SSL_CERT_FILE=%s", proxy_cert_file))
}
}
if proxy_urls, proxy_urls_set := os.LookupEnv(PROXY_URLS); proxy_urls_set {
val, err := parseRegistryConfigs(proxy_urls)
if err != nil {
slog.Error("Unable to parse proxy configurations", slog.String("error", err.Error()))
} else {
// We only care about private registry configurations that are relevant to Go and
// filter others out at this point.
for _, cfg := range val {
if cfg.Type == GOPROXY_SERVER {
proxy_configs = append(proxy_configs, cfg)
slog.Info("Found GOPROXY server", slog.String("url", cfg.URL))
}
}
if len(proxy_configs) > 0 {
goproxy_val := "https://proxy.golang.org,direct"
for _, cfg := range proxy_configs {
goproxy_val = cfg.URL + "," + goproxy_val
}
result = append(result, fmt.Sprintf("GOPROXY=%s", goproxy_val), "GOPRIVATE=", "GONOPROXY=")
}
}
}
return result
}
// Applies private package proxy related environment variables to `cmd`.
func ApplyProxyEnvVars(cmd *exec.Cmd) {
slog.Debug(
"Applying private registry proxy environment variables",
slog.String("cmd_args", strings.Join(cmd.Args, " ")),
)
// If we haven't done so yet, check whether the proxy environment variables are set
// and extract information from them.
if !proxy_vars_checked {
proxy_vars = getEnvVars()
proxy_vars_checked = true
}
// If the proxy is configured, `proxy_vars` will be not `nil`. We append those
// variables to the existing environment to preserve those environment variables.
// If `cmd.Env` is not changed, then the existing environment is also preserved.
if proxy_vars != nil {
cmd.Env = append(os.Environ(), proxy_vars...)
}
}

View File

@@ -0,0 +1,49 @@
package util
import (
"testing"
)
func parseRegistryConfigsFail(t *testing.T, str string) {
_, err := parseRegistryConfigs(str)
if err == nil {
t.Fatal("Expected `parseRegistryConfigs` to fail, but it succeeded.")
}
}
func parseRegistryConfigsSuccess(t *testing.T, str string) []RegistryConfig {
val, err := parseRegistryConfigs(str)
if err != nil {
t.Fatalf("Expected `parseRegistryConfigs` to succeed, but it failed: %s", err.Error())
}
return val
}
func TestParseRegistryConfigs(t *testing.T) {
parseRegistryConfigsFail(t, "")
empty := parseRegistryConfigsSuccess(t, "[]")
if len(empty) != 0 {
t.Fatal("Expected `parseRegistryConfigs(\"[]\")` to return no configurations, but got some.")
}
single := parseRegistryConfigsSuccess(t, "[{ \"type\": \"goproxy_server\", \"url\": \"https://proxy.example.com/mod\" }]")
if len(single) != 1 {
t.Fatalf("Expected `parseRegistryConfigs` to return one configuration, but got %d.", len(single))
}
first := single[0]
if first.Type != "goproxy_server" {
t.Fatalf("Expected `Type` to be `goproxy_server`, but got `%s`", first.Type)
}
if first.URL != "https://proxy.example.com/mod" {
t.Fatalf("Expected `URL` to be `https://proxy.example.com/mod`, but got `%s`", first.URL)
}
}

View File

@@ -210,6 +210,7 @@ void codeql::extractSwiftFiles(SwiftExtractorState& state, swift::CompilerInstan
auto inputFiles = collectInputFilenames(compiler);
std::vector<swift::ModuleDecl*> todo = collectLoadedModules(compiler);
state.encounteredModules.insert(todo.begin(), todo.end());
LOG_DEBUG("{} modules loaded", todo.size());
while (!todo.empty()) {
auto module = todo.back();
@@ -223,13 +224,18 @@ void codeql::extractSwiftFiles(SwiftExtractorState& state, swift::CompilerInstan
}
isFromSourceFile = true;
if (inputFiles.count(sourceFile->getFilename().str()) == 0) {
LOG_DEBUG("skipping module {} from file {}, not in input files", module->getName().get(),
sourceFile->getFilename());
continue;
}
LOG_DEBUG("extracting module {} from input file {}", module->getName().get(),
sourceFile->getFilename());
archiveFile(state.configuration, *sourceFile);
encounteredModules =
extractDeclarations(state, compiler, *module, sourceFile, /*lazy declaration*/ nullptr);
}
if (!isFromSourceFile) {
LOG_DEBUG("extracting module {} from non-source file", module->getName().get());
encounteredModules = extractDeclarations(state, compiler, *module, /*source file*/ nullptr,
/*lazy declaration*/ nullptr);
}

View File

@@ -93,6 +93,7 @@ class Observer : public swift::FrontendObserver {
explicit Observer(const codeql::SwiftExtractorConfiguration& config) : state{config} {}
void parsedArgs(swift::CompilerInvocation& invocation) override {
LOG_DEBUG("{}()", __func__);
auto& options = invocation.getFrontendOptions();
options.KeepASTContext = true;
lockOutputSwiftModuleTraps(state, options);
@@ -101,18 +102,21 @@ class Observer : public swift::FrontendObserver {
}
void configuredCompiler(swift::CompilerInstance& instance) override {
LOG_DEBUG("{}()", __func__);
// remove default consumers to avoid double messaging
instance.getDiags().takeConsumers();
instance.addDiagnosticConsumer(&diagConsumer);
}
void performedCompilation(swift::CompilerInstance& compiler) override {
LOG_DEBUG("{}()", __func__);
codeql::extractSwiftFiles(state, compiler);
codeql::extractSwiftInvocation(state, compiler, invocationTrap);
codeql::extractExtractLazyDeclarations(state, compiler);
}
void markSuccessfullyExtractedFiles() {
LOG_DEBUG("{}()", __func__);
codeql::SwiftLocationExtractor locExtractor{invocationTrap};
for (const auto& src : state.sourceFiles) {
auto fileLabel = locExtractor.emitFile(src);

View File

@@ -13,7 +13,7 @@ In order to perform a Swift update:
`SwiftTagTraits.h`](../../extractor/infra/SwiftTagTraits.h).
5. Open a draft PR with the overridden artifacts. Make sure CI passes, go back to 4. otherwise.
6. Run DCA, got back to 4. in case of problems.
7. Once you are happy, do
7. Once you are happy, run the following from the root of the CodeQL repository:
```bash
bazel run //swift/third_party/resources:update-dir-macos
bazel run //swift/third_party/resources:update-dir-linux