]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: don't skip PPARAMOUT in esccall after varargs
authorIan Lance Taylor <iant@golang.org>
Tue, 29 Mar 2016 14:30:17 +0000 (07:30 -0700)
committerIan Lance Taylor <iant@golang.org>
Wed, 30 Mar 2016 02:43:08 +0000 (02:43 +0000)
Fixes bug I introduced in CL 21202.

Fixes #15013.

Change-Id: I2344d7e22b8273425a0a56f4a77588b5c6e4d8c6
Reviewed-on: https://go-review.googlesource.com/21270
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/cmd/compile/internal/gc/esc.go
test/fixedbugs/issue15013.go [new file with mode: 0644]

index 51e6371c6ddba488c4e8a9f22f0b4c1770c20776..2820c8aad709b1efa0621aa8edf1feff551b313d 100644 (file)
@@ -1478,17 +1478,16 @@ func esccall(e *EscState, n *Node, up *Node) {
                lls := ll.Slice()
                sawRcvr := false
                var src *Node
-       DclLoop:
                for _, n2 := range fn.Name.Defn.Func.Dcl {
                        switch n2.Class {
                        case PPARAM:
                                if n.Op != OCALLFUNC && !sawRcvr {
                                        escassignNilWhy(e, n2, n.Left.Left, "call receiver")
                                        sawRcvr = true
-                                       continue DclLoop
+                                       continue
                                }
                                if len(lls) == 0 {
-                                       continue DclLoop
+                                       continue
                                }
                                src = lls[0]
                                if n2.Isddd && !n.Isddd {
@@ -1502,7 +1501,17 @@ func esccall(e *EscState, n *Node, up *Node) {
                                }
                                escassignNilWhy(e, n2, src, "arg to recursive call")
                                if src != lls[0] {
-                                       break DclLoop
+                                       // "..." arguments are untracked
+                                       for _, n2 := range lls {
+                                               if Debug['m'] > 3 {
+                                                       fmt.Printf("%v::esccall:: ... <- %v, untracked\n", linestr(lineno), Nconv(n2, FmtShort))
+                                               }
+                                               escassignSinkNilWhy(e, src, n2, "... arg to recursive call")
+                                       }
+                                       // No more PPARAM processing, but keep
+                                       // going for PPARAMOUT.
+                                       lls = nil
+                                       continue
                                }
                                lls = lls[1:]
 
@@ -1511,14 +1520,6 @@ func esccall(e *EscState, n *Node, up *Node) {
                        }
                }
 
-               // "..." arguments are untracked
-               for _, n2 := range lls {
-                       if Debug['m'] > 3 {
-                               fmt.Printf("%v::esccall:: ... <- %v, untracked\n", linestr(lineno), Nconv(n2, FmtShort))
-                       }
-                       escassignSinkNilWhy(e, src, n2, "... arg to recursive call")
-               }
-
                return
        }
 
diff --git a/test/fixedbugs/issue15013.go b/test/fixedbugs/issue15013.go
new file mode 100644 (file)
index 0000000..4520d4c
--- /dev/null
@@ -0,0 +1,24 @@
+// compile
+
+// Copyright 2016 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.
+
+// CL 21202 introduced a compiler crash in the handling of a varargs
+// function in the same recursive group as a function that calls it.
+// Nothing in the standard library caught the problem, so adding a test.
+
+package p
+
+func F1(p *int, a ...*int) (int, *int) {
+       if p == nil {
+               return F2(), a[0]
+       }
+       return 0, a[0]
+}
+
+func F2() int {
+       var i0, i1 int
+       a, _ := F1(&i0, &i1)
+       return a
+}