]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.8] cmd/compile: repaired loop-finder to handle trickier nesting
authorDavid Chase <drchase@google.com>
Thu, 23 Feb 2017 18:49:25 +0000 (13:49 -0500)
committerAustin Clements <austin@google.com>
Wed, 5 Apr 2017 16:58:17 +0000 (16:58 +0000)
The loop-A-encloses-loop-C code did not properly handle the
case where really C was already known to be enclosed by B,
and A was nearest-outer to B, not C.

Fixes #19217.

Change-Id: I755dd768e823cb707abdc5302fed39c11cdb34d4
Reviewed-on: https://go-review.googlesource.com/39596
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/compile/internal/ssa/likelyadjust.go
test/fixedbugs/issue19217.go [new file with mode: 0644]

index 38a5e81f916b3ca5739f1ac0ee5c01024ca10f4c..a4e5534cf884c595e3691aaa07ef5b4db90d19f3 100644 (file)
@@ -33,13 +33,24 @@ type loop struct {
 
 // outerinner records that outer contains inner
 func (sdom SparseTree) outerinner(outer, inner *loop) {
+       // There could be other outer loops found in some random order,
+       // locate the new outer loop appropriately among them.
        oldouter := inner.outer
-       if oldouter == nil || sdom.isAncestorEq(oldouter.header, outer.header) {
-               inner.outer = outer
-               outer.isInner = false
-               if inner.containsCall {
-                       outer.setContainsCall()
-               }
+       for oldouter != nil && sdom.isAncestor(outer.header, oldouter.header) {
+               inner = oldouter
+               oldouter = inner.outer
+       }
+       if outer == oldouter {
+               return
+       }
+       if oldouter != nil {
+               outer.outer = oldouter
+       }
+
+       inner.outer = outer
+       outer.isInner = false
+       if inner.containsCall {
+               outer.setContainsCall()
        }
 }
 
diff --git a/test/fixedbugs/issue19217.go b/test/fixedbugs/issue19217.go
new file mode 100644 (file)
index 0000000..9679406
--- /dev/null
@@ -0,0 +1,39 @@
+// compile
+
+// Copyright 2017 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 foo
+
+import (
+       "encoding/binary"
+)
+
+type DbBuilder struct {
+       arr []int
+}
+
+func (bld *DbBuilder) Finish() error {
+       defer bld.Finish()
+
+       var hash []byte
+       for _, ixw := range bld.arr {
+               for {
+                       if ixw != 0 {
+                               panic("ixw != 0")
+                       }
+                       ixw--
+               insertOne:
+                       for {
+                               for i := 0; i < 1; i++ {
+                                       if binary.LittleEndian.Uint16(hash[i:]) == 0 {
+                                               break insertOne
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return nil
+}