]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix duplicate code generation in swt.go
authorMatthew Dempsky <mdempsky@google.com>
Tue, 13 Mar 2018 22:07:12 +0000 (15:07 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Thu, 15 Mar 2018 01:01:56 +0000 (01:01 +0000)
When combining adjacent type switch cases with the same type hash, we
failed to actually remove the combined cases, so we would generate
code for them twice.

We use MD5 for type hashes, so collisions are rare, but they do
currently appear in test/fixedbugs/bug248.dir/bug2.go, which is how I
noticed this failure.

Passes toolstash-check.

Change-Id: I66729b3366b96cb8ddc8fa6f3ebea11ef6d74012
Reviewed-on: https://go-review.googlesource.com/100461
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
src/cmd/compile/internal/gc/swt.go

index 404a88444ac0a264f01519cb70166ed820b82337..cc69d86870c615f879dd29206c00382165dfc964 100644 (file)
@@ -803,19 +803,19 @@ func (s *typeSwitch) walk(sw *Node) {
                }
 
                // combine adjacent cases with the same hash
-               ncase := 0
-               for i := 0; i < run; i++ {
-                       ncase++
+               var batch []caseClause
+               for i, j := 0, 0; i < run; i = j {
                        hash := []*Node{cc[i].node.Right}
-                       for j := i + 1; j < run && cc[i].hash == cc[j].hash; j++ {
+                       for j = i + 1; j < run && cc[i].hash == cc[j].hash; j++ {
                                hash = append(hash, cc[j].node.Right)
                        }
                        cc[i].node.Right = liststmt(hash)
+                       batch = append(batch, cc[i])
                }
 
                // binary search among cases to narrow by hash
-               cas = append(cas, s.walkCases(cc[:ncase]))
-               cc = cc[ncase:]
+               cas = append(cas, s.walkCases(batch))
+               cc = cc[run:]
        }
 
        // handle default case