Skip to content

Commit 290b415

Browse files
committed
[dev.regabi] cmd/compile: fix ICE due to large uint64 constants
It's an error to call Int64Val on constants that don't fit into int64. CL 272654 made the compiler stricter about detecting misuse, and revealed that we were using it improperly in detecting consecutive integer-switch cases. That particular usage actually did work in practice, but it's easy and best to just fix it. Fixes #43480. Change-Id: I56f722d75e83091638ac43b80e45df0b0ad7d48d Reviewed-on: https://go-review.googlesource.com/c/go/+/281272 Trust: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
1 parent a30fd52 commit 290b415

File tree

2 files changed

+39
-1
lines changed

2 files changed

+39
-1
lines changed

src/cmd/compile/internal/walk/switch.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,15 @@ func (s *exprSwitch) flush() {
201201

202202
// Merge consecutive integer cases.
203203
if s.exprname.Type().IsInteger() {
204+
consecutive := func(last, next constant.Value) bool {
205+
delta := constant.BinaryOp(next, token.SUB, last)
206+
return constant.Compare(delta, token.EQL, constant.MakeInt64(1))
207+
}
208+
204209
merged := cc[:1]
205210
for _, c := range cc[1:] {
206211
last := &merged[len(merged)-1]
207-
if last.jmp == c.jmp && ir.Int64Val(last.hi)+1 == ir.Int64Val(c.lo) {
212+
if last.jmp == c.jmp && consecutive(last.hi.Val(), c.lo.Val()) {
208213
last.hi = c.lo
209214
} else {
210215
merged = append(merged, c)

test/fixedbugs/issue43480.go

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// run
2+
3+
// Copyright 2020 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+
// Issue #43480: ICE on large uint64 constants in switch cases.
8+
9+
package main
10+
11+
func isPow10(x uint64) bool {
12+
switch x {
13+
case 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
14+
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19:
15+
return true
16+
}
17+
return false
18+
}
19+
20+
func main() {
21+
var x uint64 = 1
22+
23+
for {
24+
if !isPow10(x) || isPow10(x-1) || isPow10(x+1) {
25+
panic(x)
26+
}
27+
next := x * 10
28+
if next/10 != x {
29+
break // overflow
30+
}
31+
x = next
32+
}
33+
}

0 commit comments

Comments
 (0)