Skip to content

Commit 43c6106

Browse files
authored
Merge pull request #22671 from owen-mc/go/fix/go-panic-abrupt-completion
Go: fix CFG bug - no control flow beyond `go panic()`
2 parents a0e81b2 + 1b6ad90 commit 43c6106

4 files changed

Lines changed: 13 additions & 3 deletions

File tree

‎go/ql/lib/semmle/go/controlflow/ControlFlowGraphImpl.qll‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,9 @@ module CfgImpl {
664664
/** Helper: blank identifier check */
665665
private predicate notBlankIdent(Go::Expr e) { not e instanceof Go::BlankIdent }
666666

667+
/** Holds if `e` is invoked in a newly started goroutine. */
668+
private predicate isGoStmtCall(Ast::AstNode e) { e = any(Go::GoStmt s).getCall() }
669+
667670
/** Helper: implicit field selection for promoted selectors */
668671
additional predicate implicitFieldSelection(Ast::AstNode e, int index, Go::Field implicitField) {
669672
exists(Go::StructType baseType, Go::PromotedField child, int implicitFieldDepth |
@@ -704,6 +707,7 @@ module CfgImpl {
704707
Ast::AstNode ast, PreControlFlowNode n, AbruptCompletion c, boolean always
705708
) {
706709
ast instanceof Go::CallExpr and
710+
not isGoStmtCall(ast) and
707711
(
708712
not exists(ast.(Go::CallExpr).getTarget()) or
709713
ast.(Go::CallExpr).getTarget().mayPanic()
@@ -727,6 +731,7 @@ module CfgImpl {
727731
// exception completion so that the shared library's default In->After step
728732
// is suppressed.
729733
ast instanceof Go::CallExpr and
734+
not isGoStmtCall(ast) and
730735
exists(Go::Function target | target = ast.(Go::CallExpr).getTarget() |
731736
target.mustPanic() or target.mustNotReturnNormally()
732737
) and
@@ -848,6 +853,7 @@ module CfgImpl {
848853
private predicate mayPanic(Ast::AstNode ast) {
849854
ast instanceof Go::CallExpr and
850855
not ast = any(Go::DeferStmt s).getCall() and
856+
not isGoStmtCall(ast) and
851857
(not exists(ast.(Go::CallExpr).getTarget()) or ast.(Go::CallExpr).getTarget().mayPanic()) and
852858
not exists(Go::Function target | target = ast.(Go::CallExpr).getTarget() |
853859
target.mustNotReturnNormally() and not target.mustPanic()

‎go/ql/test/library-tests/semmle/go/controlflow/ControlFlowGraph/ControlFlowNode_getASuccessor.expected‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3127,7 +3127,6 @@
31273127
| stmts.go:135:3:135:14 | expression statement | stmts.go:135:3:135:14 | Before call to test5 |
31283128
| stmts.go:135:9:135:13 | false | stmts.go:135:3:135:14 | call to test5 |
31293129
| stmts.go:140:1:142:1 | Entry | stmts.go:140:13:140:13 | f |
3130-
| stmts.go:140:1:142:1 | Exceptional Exit | stmts.go:140:1:142:1 | Exit |
31313130
| stmts.go:140:1:142:1 | Normal Exit | stmts.go:140:1:142:1 | Exit |
31323131
| stmts.go:140:1:142:1 | function declaration | stmts.go:145:1:159:1 | function declaration |
31333132
| stmts.go:140:13:140:13 | f | stmts.go:140:23:142:1 | block statement |
@@ -3139,7 +3138,6 @@
31393138
| stmts.go:141:5:141:5 | f | stmts.go:141:5:141:7 | call to f |
31403139
| stmts.go:141:5:141:7 | After call to f | stmts.go:141:2:141:7 | go statement |
31413140
| stmts.go:141:5:141:7 | Before call to f | stmts.go:141:5:141:5 | f |
3142-
| stmts.go:141:5:141:7 | call to f | stmts.go:140:1:142:1 | Exceptional Exit |
31433141
| stmts.go:141:5:141:7 | call to f | stmts.go:141:5:141:7 | After call to f |
31443142
| stmts.go:145:1:159:1 | Entry | stmts.go:145:13:145:14 | xs |
31453143
| stmts.go:145:1:159:1 | Exceptional Exit | stmts.go:145:1:159:1 | Exit |

‎go/ql/test/query-tests/RedundantCode/UnreachableStatement/CONSISTENCY/CfgConsistency.expected‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
consistencyOverview
2-
| deadEnd | 9 |
2+
| deadEnd | 10 |
33
deadEnd
44
| main.go:17:2:17:10 | select statement |
55
| main.go:109:2:109:10 | select statement |
@@ -10,3 +10,4 @@ deadEnd
1010
| main.go:145:2:145:10 | select statement |
1111
| main.go:151:2:151:10 | select statement |
1212
| main.go:157:2:157:10 | select statement |
13+
| main.go:164:2:164:10 | select statement |

‎go/ql/test/query-tests/RedundantCode/UnreachableStatement/main.go‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,4 +159,9 @@ func test19() mystruct {
159159
return mystruct{test10(1), test10(2) == 2} // $ Alert
160160
}
161161

162+
func test20() {
163+
go panic("panic in another goroutine")
164+
select {} // OK: reachable after starting the goroutine
165+
}
166+
162167
func main() {}

0 commit comments

Comments
 (0)