]> Cypherpunks repositories - gostls13.git/commitdiff
gc: bug293
authorRuss Cox <rsc@golang.org>
Thu, 15 Jul 2010 23:14:06 +0000 (16:14 -0700)
committerRuss Cox <rsc@golang.org>
Thu, 15 Jul 2010 23:14:06 +0000 (16:14 -0700)
Fixes #846.

R=ken2
CC=golang-dev
https://golang.org/cl/1862042

src/cmd/5g/ggen.c
src/cmd/6g/ggen.c
src/cmd/8g/ggen.c
src/cmd/gc/walk.c
test/fixedbugs/bug293.go [new file with mode: 0644]

index bbcb7f728fa66ec76c6d539857419c81be0c8618..2776ac7681e99db641be935a64266311549d0b05 100644 (file)
@@ -87,12 +87,12 @@ compile(Node *fn)
 
        if(pret)
                patch(pret, pc);
+       if(hasdefer)
+               ginscall(deferreturn, 0);
        if(curfn->exit)
                genlist(curfn->exit);
        if(nerrors != 0)
                goto ret;
-       if(hasdefer)
-               ginscall(deferreturn, 0);
        pc->as = ARET;  // overwrite AEND
        pc->lineno = lineno;
 
index 21b6237a31096d8cf3d4ba663e9bca516fe7bb31..c7a4a642e64ccfe7ae9ee0ecdefbce45f4151c23 100644 (file)
@@ -90,13 +90,13 @@ compile(Node *fn)
        if(pret)
                patch(pret, pc);
        ginit();
+       if(hasdefer)
+               ginscall(deferreturn, 0);
        if(curfn->exit)
                genlist(curfn->exit);
        gclean();
        if(nerrors != 0)
                goto ret;
-       if(hasdefer)
-               ginscall(deferreturn, 0);
        pc->as = ARET;  // overwrite AEND
        pc->lineno = lineno;
 
index e9a5454eb2f5dfbbda5d6e258c56a2a962e8e714..7fbbdd344182840a456dccfae65ac77dc9b25ec6 100644 (file)
@@ -92,11 +92,6 @@ compile(Node *fn)
        if(pret)
                patch(pret, pc);
        ginit();
-       if(curfn->exit)
-               genlist(curfn->exit);
-       gclean();
-       if(nerrors != 0)
-               goto ret;
        if(hasdefer) {
                // On Native client, insert call to no-op function
                // to force alignment immediately before call to deferreturn,
@@ -107,6 +102,11 @@ compile(Node *fn)
                        ginscall(naclnop, 0);
                ginscall(deferreturn, 0);
        }
+       if(curfn->exit)
+               genlist(curfn->exit);
+       gclean();
+       if(nerrors != 0)
+               goto ret;
        pc->as = ARET;  // overwrite AEND
        pc->lineno = lineno;
 
index 50d2ba3ea10229b71cf242eb00d69d819815a3e4..78365353b3c643c4b31491ff1eaa4783d5da6c51 100644 (file)
@@ -365,7 +365,7 @@ walkstmt(Node **np)
        NodeList *init;
        NodeList *ll, *rl;
        int cl, lno;
-       Node *n;
+       Node *n, *f;
 
        n = *np;
        if(n == N)
@@ -492,6 +492,14 @@ walkstmt(Node **np)
                                n->list = nil;
                                break;
                        }
+                       if(count(n->list) == 1 && count(rl) > 1) {
+                               // OAS2FUNC in disguise
+                               f = n->list->n;
+                               if(f->op != OCALLFUNC && f->op != OCALLMETH && f->op != OCALLINTER)
+                                       fatal("expected return of call, have %#N", f);
+                               n->list = concat(list1(f), ascompatet(n->op, rl, &f->type, 0, &n->ninit));
+                               break;
+                       }
                        ll = ascompatee(n->op, rl, n->list, &n->ninit);
                        n->list = reorder3(ll);
                        break;
diff --git a/test/fixedbugs/bug293.go b/test/fixedbugs/bug293.go
new file mode 100644 (file)
index 0000000..ca9b71a
--- /dev/null
@@ -0,0 +1,37 @@
+// $G $D/$F.go && $L $F.$A && ./$A.out
+
+// Copyright 2010 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.
+
+// http://code.google.com/p/go/issues/detail?id=846
+
+package main
+
+func x() (a int, b bool) {
+       defer func(){
+               a++
+       }()
+       a, b = y()
+       return
+}
+
+func x2() (a int, b bool) {
+       defer func(){
+               a++
+       }()
+       return y()
+}
+
+func y() (int, bool) {
+       return 4, false
+}
+
+func main() {
+       if a, _ := x(); a != 5 {
+               println("BUG", a)
+       }
+       if a, _ := x2(); a != 5 {
+               println("BUG", a)
+       }
+}