]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/6g: fix componentgen for funarg structs.
authorRémy Oudompheng <oudomphe@phare.normalesup.org>
Mon, 17 Dec 2012 21:29:43 +0000 (22:29 +0100)
committerRémy Oudompheng <oudomphe@phare.normalesup.org>
Mon, 17 Dec 2012 21:29:43 +0000 (22:29 +0100)
Fixes #4518.

R=golang-dev, rsc
CC=golang-dev
https://golang.org/cl/6932045

src/cmd/6g/cgen.c
test/fixedbugs/issue4518.go [new file with mode: 0644]

index aa947875925d1effef8b1d6b864b4d595c375a2b..eff81e2a7eab044d635969d818e950a6bd8e9e73 100644 (file)
@@ -1632,6 +1632,12 @@ componentgen(Node *nr, Node *nl)
        case TSTRUCT:
                loffset = nodl.xoffset;
                roffset = nodr.xoffset;
+               // funarg structs may not begin at offset zero.
+               if(nl->type->etype == TSTRUCT && nl->type->funarg && nl->type->type)
+                       loffset -= nl->type->type->width;
+               if(nr != N && nr->type->etype == TSTRUCT && nr->type->funarg && nr->type->type)
+                       roffset -= nr->type->type->width;
+
                for(t=nl->type->type; t; t=t->down) {
                        nodl.xoffset = loffset + t->width;
                        nodl.type = t->type;
diff --git a/test/fixedbugs/issue4518.go b/test/fixedbugs/issue4518.go
new file mode 100644 (file)
index 0000000..e64b069
--- /dev/null
@@ -0,0 +1,67 @@
+// run
+
+// Copyright 2012 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.
+
+// Issue 4518. In some circumstances "return F(...)"
+// where F has multiple returns is miscompiled by 6g due to
+// bold assumptions in componentgen.
+
+package main
+
+func DontInline() {}
+
+func F(e interface{}) (int, int) {
+       DontInline()
+       return 3, 7
+}
+
+func G() (int, int) {
+       DontInline()
+       return 3, 7
+}
+
+func bogus1(d interface{}) (int, int) {
+       switch {
+       default:
+               return F(d)
+       }
+       return 0, 0
+}
+
+func bogus2() (int, int) {
+       switch {
+       default:
+               return F(3)
+       }
+       return 0, 0
+}
+
+func bogus3(d interface{}) (int, int) {
+       switch {
+       default:
+               return G()
+       }
+       return 0, 0
+}
+
+func bogus4() (int, int) {
+       switch {
+       default:
+               return G()
+       }
+       return 0, 0
+}
+
+func check(a, b int) {
+       if a != 3 || b != 7 {
+               println(a, b)
+               panic("a != 3 || b != 7")
+       }
+}
+
+func main() {
+       check(bogus1(42))
+       check(bogus2())
+}