From f6509cf5cdbb5787061b784973782933c47f1782 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Wed, 20 Dec 2023 15:38:50 -0800 Subject: [PATCH] cmd/compile: handle constant-folding of an out-of-range jump table index The input index to a jump table can be out of range for unreachable code. Dynamically the compiler ensures that an out-of-range index can never reach a jump table, but that guarantee doesn't extend to the static realm. Fixes #64826 Change-Id: I5829f3933ae5124ffad8337dfd7dd75e67a8ec33 Reviewed-on: https://go-review.googlesource.com/c/go/+/552055 Reviewed-by: Keith Randall LUCI-TryBot-Result: Go LUCI Reviewed-by: David Chase --- src/cmd/compile/internal/ssa/sccp.go | 7 +++++ test/fixedbugs/issue64826.go | 38 ++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 test/fixedbugs/issue64826.go 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 +} -- 2.48.1