]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/6g: handle very wide offsets.
authorRémy Oudompheng <oudomphe@phare.normalesup.org>
Mon, 9 Sep 2013 18:36:19 +0000 (20:36 +0200)
committerRémy Oudompheng <oudomphe@phare.normalesup.org>
Mon, 9 Sep 2013 18:36:19 +0000 (20:36 +0200)
Fixes #6036.

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

src/cmd/6g/cgen.c
src/cmd/6g/gg.h
src/cmd/6g/gsubr.c
test/fixedbugs/issue6036.go [new file with mode: 0644]

index d08caf6c250ab061ee4e5abef8c1583321abe335..fd79c099b11113ba2949ed8aaa85e6eb08a0f7b8 100644 (file)
@@ -937,6 +937,7 @@ igen(Node *n, Node *a, Node *res)
                igen(n->left, a, res);
                a->xoffset += n->xoffset;
                a->type = n->type;
+               fixlargeoffset(a);
                return;
 
        case ODOTPTR:
@@ -945,6 +946,7 @@ igen(Node *n, Node *a, Node *res)
                a->op = OINDREG;
                a->xoffset += n->xoffset;
                a->type = n->type;
+               fixlargeoffset(a);
                return;
 
        case OCALLFUNC:
@@ -993,6 +995,7 @@ igen(Node *n, Node *a, Node *res)
                        // Compute &a[i] as &a + i*width.
                        a->type = n->type;
                        a->xoffset += mpgetfix(n->right->val.u.xval)*n->type->width;
+                       fixlargeoffset(a);
                        return;
                }
        }
index f2f3ac1c16b7366a952e10162e358620422e322b..3ef59c788e2e4c6150a4a95f5cc019034f03a516 100644 (file)
@@ -132,6 +132,7 @@ void        afunclit(Addr*, Node*);
 void   nodfconst(Node*, Type*, Mpflt*);
 void   gtrack(Sym*);
 void   gargsize(vlong);
+void   fixlargeoffset(Node *n);
 
 /*
  * cplx.c
index 9e8a2b229a3a1d00c558ab640ddd58dbcaa0bb84..0e45cc0ebe560db88271355788553a21f04fc362 100644 (file)
@@ -1067,6 +1067,29 @@ gins(int as, Node *f, Node *t)
        return p;
 }
 
+void
+fixlargeoffset(Node *n)
+{
+       Node a;
+
+       if(n == N)
+               return;
+       if(n->op != OINDREG)
+               return;
+       if(n->val.u.reg == D_SP) // stack offset cannot be large
+               return;
+       if(n->xoffset != (int32)n->xoffset) {
+               // offset too large, add to register instead.
+               a = *n;
+               a.op = OREGISTER;
+               a.type = types[tptr];
+               a.xoffset = 0;
+               cgen_checknil(&a);
+               ginscon(optoas(OADD, types[tptr]), n->xoffset, &a);
+               n->xoffset = 0;
+       }
+}
+
 /*
  * generate code to compute n;
  * make a refer to result.
@@ -2015,6 +2038,7 @@ odot:
 
        a->type = D_NONE;
        a->index = D_NONE;
+       fixlargeoffset(&n1);
        naddr(&n1, a, 1);
        goto yes;
 
@@ -2176,6 +2200,7 @@ oindex_const:
                n2 = *reg;
                n2.op = OINDREG;
                n2.xoffset = v*w;
+               fixlargeoffset(&n2);
                a->type = D_NONE;
                a->index = D_NONE;
                naddr(&n2, a, 1);
@@ -2188,6 +2213,7 @@ oindex_const:
                reg->op = OREGISTER;
        }
        n1.xoffset += v*w;
+       fixlargeoffset(&n1);
        a->type = D_NONE;
        a->index= D_NONE;
        naddr(&n1, a, 1);
@@ -2223,6 +2249,7 @@ oindex_const_sudo:
        n2 = *reg;
        n2.op = OINDREG;
        n2.xoffset = v*w;
+       fixlargeoffset(&n2);
        a->type = D_NONE;
        a->index = D_NONE;
        naddr(&n2, a, 1);
diff --git a/test/fixedbugs/issue6036.go b/test/fixedbugs/issue6036.go
new file mode 100644 (file)
index 0000000..5f787c5
--- /dev/null
@@ -0,0 +1,44 @@
+// +build amd64
+// compile
+
+// Copyright 2013 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 6036: 6g's backend generates OINDREG with
+// offsets larger than 32-bit.
+
+package main
+
+type T struct {
+       Large [1 << 31]byte
+       A     int
+       B     int
+}
+
+func F(t *T) {
+       t.B = t.A
+}
+
+type T2 [1<<31 + 2]byte
+
+func F2(t *T2) {
+       t[1<<31+1] = 42
+}
+
+type T3 [1<<15 + 1][1<<15 + 1]int
+
+func F3(t *T3) {
+       t[1<<15][1<<15] = 42
+}
+
+type S struct {
+       A int32
+       B int32
+}
+
+type T4 [1<<29 + 1]S
+
+func F4(t *T4) {
+       t[1<<29].B = 42
+}