]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: modify swt.go to skip repeated walks of switch
authorDavid Chase <drchase@google.com>
Fri, 4 Jan 2019 16:43:23 +0000 (11:43 -0500)
committerDavid Chase <drchase@google.com>
Fri, 4 Jan 2019 21:51:37 +0000 (21:51 +0000)
The compiler appears to contain several squirrelly corner
cases where nodes are double walked, some where new nodes
are created from walked parts.  Rather than trust that we
had searched hard enough for the last one, change
exprSwitch.walk() to return immediately if it has already
been walked.  This appears to be the only case where
double-walking a node is actually harmful.

Fixes #29562.

Change-Id: I0667e8769aba4c3236666cd836a934e256c0bfc5
Reviewed-on: https://go-review.googlesource.com/c/156317
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/gc/swt.go
test/fixedbugs/issue29562.go [new file with mode: 0644]

index a985626a02e265614ba0d433a50e5cc67190a42b..cc9a8f8b2cd735519cdeb8a5585c7d89e819cc10 100644 (file)
@@ -243,7 +243,7 @@ func walkswitch(sw *Node) {
 func (s *exprSwitch) walk(sw *Node) {
        // Guard against double walk, see #25776.
        if sw.List.Len() == 0 && sw.Nbody.Len() > 0 {
-               Fatalf("second walk of switch")
+               return // Was fatal, but eliminating every possible source of double-walking is hard
        }
 
        casebody(sw, nil)
@@ -302,7 +302,7 @@ func (s *exprSwitch) walk(sw *Node) {
                s.exprname = cond
        } else {
                s.exprname = temp(cond.Type)
-               cas = []*Node{nod(OAS, s.exprname, cond)}
+               cas = []*Node{nod(OAS, s.exprname, cond)} // This gets walk()ed again in walkstmtlist just before end of this function.  See #29562.
                typecheckslice(cas, ctxStmt)
        }
 
diff --git a/test/fixedbugs/issue29562.go b/test/fixedbugs/issue29562.go
new file mode 100644 (file)
index 0000000..cbcd77d
--- /dev/null
@@ -0,0 +1,26 @@
+// compile
+
+// Copyright 2019 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.
+
+// Triggers a double walk of the (inlined) switch in il
+
+package p
+
+func il(s string) string {
+       switch len(s) {
+       case 0:
+               return "zero"
+       case 1:
+               return "one"
+       }
+       return s
+}
+
+func f() {
+       var s string
+       var as []string
+       switch false && (s+"a"+as[0]+il(s)+as[0]+s == "") {
+       }
+}