]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: fix ICE due to large uint64 constants
authorMatthew Dempsky <mdempsky@google.com>
Sun, 3 Jan 2021 22:24:25 +0000 (14:24 -0800)
committerMatthew Dempsky <mdempsky@google.com>
Mon, 4 Jan 2021 10:30:07 +0000 (10:30 +0000)
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>
src/cmd/compile/internal/walk/switch.go
test/fixedbugs/issue43480.go [new file with mode: 0644]

index b03bc3eba7c4d9868312195b9b92308fd05a7e42..59446ef3dbab49129a848377eb172f34a15ac3e8 100644 (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)
diff --git a/test/fixedbugs/issue43480.go b/test/fixedbugs/issue43480.go
new file mode 100644 (file)
index 0000000..d98ad3a
--- /dev/null
@@ -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
+       }
+}