Skip to content

Commit f6509cf

Browse files
committed
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 <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: David Chase <[email protected]>
1 parent adec22b commit f6509cf

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

src/cmd/compile/internal/ssa/sccp.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,13 @@ func rewireSuccessor(block *Block, constVal *Value) bool {
535535
case BlockJumpTable:
536536
// Remove everything but the known taken branch.
537537
idx := int(constVal.AuxInt)
538+
if idx < 0 || idx >= len(block.Succs) {
539+
// This can only happen in unreachable code,
540+
// as an invariant of jump tables is that their
541+
// input index is in range.
542+
// See issue 64826.
543+
return false
544+
}
538545
block.swapSuccessorsByIdx(0, idx)
539546
for len(block.Succs) > 1 {
540547
block.removeEdge(1)

test/fixedbugs/issue64826.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// build
2+
3+
// Copyright 2023 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
package main
8+
9+
func main() {
10+
f(g(false))
11+
}
12+
func g(b bool) string {
13+
if b {
14+
return "z"
15+
}
16+
return "q"
17+
}
18+
func f(x string) int {
19+
switch len(x) {
20+
case 4:
21+
return 4
22+
case 5:
23+
return 5
24+
case 6:
25+
return 6
26+
case 7:
27+
return 7
28+
case 8:
29+
return 8
30+
case 9:
31+
return 9
32+
case 10:
33+
return 10
34+
case 11:
35+
return 11
36+
}
37+
return 0
38+
}

0 commit comments

Comments
 (0)