]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile: handle constant-folding of an out-of-range jump table index
authorKeith Randall <khr@golang.org>
Wed, 20 Dec 2023 23:38:50 +0000 (15:38 -0800)
committerKeith Randall <khr@golang.org>
Thu, 21 Dec 2023 00:15:58 +0000 (00:15 +0000)
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 <khr@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/ssa/sccp.go
test/fixedbugs/issue64826.go [new file with mode: 0644]

index 86c6117d872b5dc5d54a533ba874428227c456d7..77a6f509618af659efa1e715db7ab4f0823dbaa5 100644 (file)
@@ -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 (file)
index 0000000..864c474
--- /dev/null
@@ -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
+}