1
0
mirror of https://github.com/golang/go synced 2024-11-11 19:41:36 -07:00

[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>
This commit is contained in:
Matthew Dempsky 2021-01-03 14:24:25 -08:00
parent a30fd52884
commit 290b4154b7
2 changed files with 39 additions and 1 deletions

View File

@ -201,10 +201,15 @@ func (s *exprSwitch) flush() {
// Merge consecutive integer cases.
if s.exprname.Type().IsInteger() {
consecutive := func(last, next constant.Value) bool {
delta := constant.BinaryOp(next, token.SUB, last)
return constant.Compare(delta, token.EQL, constant.MakeInt64(1))
}
merged := cc[:1]
for _, c := range cc[1:] {
last := &merged[len(merged)-1]
if last.jmp == c.jmp && ir.Int64Val(last.hi)+1 == ir.Int64Val(c.lo) {
if last.jmp == c.jmp && consecutive(last.hi.Val(), c.lo.Val()) {
last.hi = c.lo
} else {
merged = append(merged, c)

View File

@ -0,0 +1,33 @@
// run
// Copyright 2020 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.
// Issue #43480: ICE on large uint64 constants in switch cases.
package main
func isPow10(x uint64) bool {
switch x {
case 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19:
return true
}
return false
}
func main() {
var x uint64 = 1
for {
if !isPow10(x) || isPow10(x-1) || isPow10(x+1) {
panic(x)
}
next := x * 10
if next/10 != x {
break // overflow
}
x = next
}
}