Commit 9c21ce54 authored by Rémy Oudompheng's avatar Rémy Oudompheng

cmd/6g: handle very wide offsets.

Fixes #6036.

R=golang-dev, bradfitz, rsc
CC=golang-dev
https://golang.org/cl/12992043
parent 0218dfe7
......@@ -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;
}
}
......
......@@ -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
......
......@@ -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);
......
// +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
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment