Skip to content

Commit 107f24e

Browse files
committed
Fix CFG for go panic()
1 parent a2d624b commit 107f24e

3 files changed

Lines changed: 7 additions & 2 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/query-tests/RedundantCode/UnreachableStatement/UnreachableStatement.expected‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,3 @@
1010
| main.go:147:2:147:17 | return statement | This statement is unreachable. |
1111
| main.go:153:2:153:22 | return statement | This statement is unreachable. |
1212
| main.go:159:2:159:43 | return statement | This statement is unreachable. |
13-
| main.go:164:2:164:10 | select statement | This statement is unreachable. |

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ func test19() mystruct {
161161

162162
func test20() {
163163
go panic("panic in another goroutine")
164-
select {} // $ SPURIOUS: Alert // reachable after starting the goroutine
164+
select {} // OK: reachable after starting the goroutine
165165
}
166166

167167
func main() {}

0 commit comments

Comments
 (0)