diff --git a/src/cmd/compile/internal/ssa/sccp.go b/src/cmd/compile/internal/ssa/sccp.go index 86c6117d87..77a6f50961 100644 --- a/src/cmd/compile/internal/ssa/sccp.go +++ b/src/cmd/compile/internal/ssa/sccp.go @@ -535,6 +535,13 @@ func rewireSuccessor(block *Block, constVal *Value) bool { case BlockJumpTable: // Remove everything but the known taken branch. idx := int(constVal.AuxInt) + if idx < 0 || idx >= len(block.Succs) { + // This can only happen in unreachable code, + // as an invariant of jump tables is that their + // input index is in range. + // See issue 64826. + return false + } block.swapSuccessorsByIdx(0, idx) for len(block.Succs) > 1 { block.removeEdge(1) diff --git a/test/fixedbugs/issue64826.go b/test/fixedbugs/issue64826.go new file mode 100644 index 0000000000..864c474a64 --- /dev/null +++ b/test/fixedbugs/issue64826.go @@ -0,0 +1,38 @@ +// build + +// Copyright 2023 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +func main() { + f(g(false)) +} +func g(b bool) string { + if b { + return "z" + } + return "q" +} +func f(x string) int { + switch len(x) { + case 4: + return 4 + case 5: + return 5 + case 6: + return 6 + case 7: + return 7 + case 8: + return 8 + case 9: + return 9 + case 10: + return 10 + case 11: + return 11 + } + return 0 +}