]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: avoid remainder in loopbce when increment=0
authorDavid Chase <drchase@google.com>
Mon, 25 Jun 2018 19:26:45 +0000 (15:26 -0400)
committerDavid Chase <drchase@google.com>
Mon, 25 Jun 2018 20:36:42 +0000 (20:36 +0000)
For non-unit increment, loopbce checks to see if the
increment evenly divides the difference between (constant)
loop start and end.  This test panics when the increment
is zero.

Fix: check for zero, if found, don't optimize the loop.

Also added missing copyright notice to loopbce.go.

Fixes #26043.

Change-Id: I5f460104879cacc94481949234c9ce8c519d6380
Reviewed-on: https://go-review.googlesource.com/120759
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/compile/internal/ssa/loopbce.go
test/fixedbugs/issue26043.go [new file with mode: 0644]

index 0c09de0bfc07464ce134d9b496859002e76ad7fd..2ab05711ad3d71c3e60194500f795e97e593df37 100644 (file)
@@ -1,3 +1,7 @@
+// Copyright 2018 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 ssa
 
 import "fmt"
@@ -154,7 +158,7 @@ nextb:
                // if the increment is ±1 or when the limits are constants.
                if inc.AuxInt != 1 && inc.AuxInt != -1 {
                        ok := false
-                       if min.Op == OpConst64 && max.Op == OpConst64 {
+                       if min.Op == OpConst64 && max.Op == OpConst64 && inc.AuxInt != 0 {
                                if max.AuxInt > min.AuxInt && max.AuxInt%inc.AuxInt == min.AuxInt%inc.AuxInt { // handle overflow
                                        ok = true
                                }
diff --git a/test/fixedbugs/issue26043.go b/test/fixedbugs/issue26043.go
new file mode 100644 (file)
index 0000000..fe32947
--- /dev/null
@@ -0,0 +1,32 @@
+// compile
+
+// Copyright 2018 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.
+
+// This program results in a loop inferred to increment
+// j by 0, causing bounds check elimination to attempt
+// something%0, which panics (in the bug).
+
+package q
+
+func f() {
+       var s1 string
+       var b bool
+       if b {
+               b = !b
+               s1 += "a"
+       }
+
+       var s2 string
+       var i, j int
+       if (s1 <= "") || (s2 >= "") {
+               j = len(s1[:6])
+       } else {
+               i = len("b")
+       }
+
+       for j < 0 {
+               j += i
+       }
+}