From 4a82483e9cc00a40d1b07a7ca9c60142697e1151 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 23 Sep 2026 15:44:33 +0100 Subject: [PATCH 1/2] Add test with spurious results for go/unreachable-statement --- .../CONSISTENCY/CfgConsistency.expected | 6 +++++- .../UnreachableStatement.expected | 1 + .../RedundantCode/UnreachableStatement/main.go | 17 +++++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/go/ql/test/query-tests/RedundantCode/UnreachableStatement/CONSISTENCY/CfgConsistency.expected b/go/ql/test/query-tests/RedundantCode/UnreachableStatement/CONSISTENCY/CfgConsistency.expected index 887fef4a49c7..c211c7317f37 100644 --- a/go/ql/test/query-tests/RedundantCode/UnreachableStatement/CONSISTENCY/CfgConsistency.expected +++ b/go/ql/test/query-tests/RedundantCode/UnreachableStatement/CONSISTENCY/CfgConsistency.expected @@ -1,5 +1,6 @@ consistencyOverview -| deadEnd | 11 | +| deadEnd | 12 | +| missingInNodeForPostOrInOrder | 1 | deadEnd | main.go:17:2:17:10 | select statement | | main.go:109:2:109:10 | select statement | @@ -12,3 +13,6 @@ deadEnd | main.go:157:2:157:10 | select statement | | main.go:164:2:164:10 | select statement | | main.go:168:2:168:10 | select statement | +| main.go:200:5:200:11 | implicit-field:0 selection of value | +missingInNodeForPostOrInOrder +| main.go:200:5:200:11 | selection of value | diff --git a/go/ql/test/query-tests/RedundantCode/UnreachableStatement/UnreachableStatement.expected b/go/ql/test/query-tests/RedundantCode/UnreachableStatement/UnreachableStatement.expected index 240cfcaf1e5e..cb7606a5405b 100644 --- a/go/ql/test/query-tests/RedundantCode/UnreachableStatement/UnreachableStatement.expected +++ b/go/ql/test/query-tests/RedundantCode/UnreachableStatement/UnreachableStatement.expected @@ -11,3 +11,4 @@ | main.go:153:2:153:22 | return statement | This statement is unreachable. | | main.go:159:2:159:43 | return statement | This statement is unreachable. | | main.go:171:2:171:14 | expression statement | This statement is unreachable. | +| main.go:203:2:203:14 | return statement | This statement is unreachable. | diff --git a/go/ql/test/query-tests/RedundantCode/UnreachableStatement/main.go b/go/ql/test/query-tests/RedundantCode/UnreachableStatement/main.go index 0dacf0c44984..a0844a569674 100644 --- a/go/ql/test/query-tests/RedundantCode/UnreachableStatement/main.go +++ b/go/ql/test/query-tests/RedundantCode/UnreachableStatement/main.go @@ -186,4 +186,21 @@ func test23() { unreachable() // OK: deliberately unreachable } +type ( + embedded struct{} + recursive struct { + *embedded + value int + *recursive + } +) + +func test24(x *recursive) []int { + values := []int{0} + if x.value != 0 { + values = append(values, x.value) + } + return values // $ SPURIOUS: Alert // BUG: reachable because value is a direct field of recursive +} + func main() {} From 596df995926a6cb911b76c7bf45173b71bec442f Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Wed, 23 Sep 2026 15:51:08 +0100 Subject: [PATCH 2/2] Fix bug - implicit field selection created with depth 0 --- go/ql/lib/semmle/go/controlflow/ControlFlowGraphImpl.qll | 5 +++-- .../CONSISTENCY/CfgConsistency.expected | 6 +----- .../UnreachableStatement/UnreachableStatement.expected | 1 - .../query-tests/RedundantCode/UnreachableStatement/main.go | 2 +- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/go/ql/lib/semmle/go/controlflow/ControlFlowGraphImpl.qll b/go/ql/lib/semmle/go/controlflow/ControlFlowGraphImpl.qll index ee7c9b1136a5..1eb9a84f50fb 100644 --- a/go/ql/lib/semmle/go/controlflow/ControlFlowGraphImpl.qll +++ b/go/ql/lib/semmle/go/controlflow/ControlFlowGraphImpl.qll @@ -682,7 +682,7 @@ module CfgImpl { e.(Go::PromotedSelector).refersTo(explicitField) and baseType.getFieldAtDepth(_, explicitFieldDepth) = explicitField | - index = explicitFieldDepth - implicitFieldDepth + index = explicitFieldDepth - implicitFieldDepth and index > 0 ) ) or @@ -692,7 +692,8 @@ module CfgImpl { baseType = e.(Go::PromotedSelector).getSelectedStructType() and e.(Go::PromotedSelector).refersTo(method) and baseType.getMethodAtDepth(_, mDepth) = method and - index = mDepth - implicitFieldDepth + index = mDepth - implicitFieldDepth and + index > 0 | method = baseType.getMethodOfEmbedded(implicitField, _, implicitFieldDepth + 1) or diff --git a/go/ql/test/query-tests/RedundantCode/UnreachableStatement/CONSISTENCY/CfgConsistency.expected b/go/ql/test/query-tests/RedundantCode/UnreachableStatement/CONSISTENCY/CfgConsistency.expected index c211c7317f37..887fef4a49c7 100644 --- a/go/ql/test/query-tests/RedundantCode/UnreachableStatement/CONSISTENCY/CfgConsistency.expected +++ b/go/ql/test/query-tests/RedundantCode/UnreachableStatement/CONSISTENCY/CfgConsistency.expected @@ -1,6 +1,5 @@ consistencyOverview -| deadEnd | 12 | -| missingInNodeForPostOrInOrder | 1 | +| deadEnd | 11 | deadEnd | main.go:17:2:17:10 | select statement | | main.go:109:2:109:10 | select statement | @@ -13,6 +12,3 @@ deadEnd | main.go:157:2:157:10 | select statement | | main.go:164:2:164:10 | select statement | | main.go:168:2:168:10 | select statement | -| main.go:200:5:200:11 | implicit-field:0 selection of value | -missingInNodeForPostOrInOrder -| main.go:200:5:200:11 | selection of value | diff --git a/go/ql/test/query-tests/RedundantCode/UnreachableStatement/UnreachableStatement.expected b/go/ql/test/query-tests/RedundantCode/UnreachableStatement/UnreachableStatement.expected index cb7606a5405b..240cfcaf1e5e 100644 --- a/go/ql/test/query-tests/RedundantCode/UnreachableStatement/UnreachableStatement.expected +++ b/go/ql/test/query-tests/RedundantCode/UnreachableStatement/UnreachableStatement.expected @@ -11,4 +11,3 @@ | main.go:153:2:153:22 | return statement | This statement is unreachable. | | main.go:159:2:159:43 | return statement | This statement is unreachable. | | main.go:171:2:171:14 | expression statement | This statement is unreachable. | -| main.go:203:2:203:14 | return statement | This statement is unreachable. | diff --git a/go/ql/test/query-tests/RedundantCode/UnreachableStatement/main.go b/go/ql/test/query-tests/RedundantCode/UnreachableStatement/main.go index a0844a569674..016920175bb7 100644 --- a/go/ql/test/query-tests/RedundantCode/UnreachableStatement/main.go +++ b/go/ql/test/query-tests/RedundantCode/UnreachableStatement/main.go @@ -200,7 +200,7 @@ func test24(x *recursive) []int { if x.value != 0 { values = append(values, x.value) } - return values // $ SPURIOUS: Alert // BUG: reachable because value is a direct field of recursive + return values // OK: reachable because value is a direct field of recursive } func main() {}