mirror of
https://github.com/golang/go
synced 2024-11-21 13:24:40 -07:00
gc: zero-width struct, zero-length array fixes
Fixes #1774. Fixes #2095. Fixes #2097. R=ken2 CC=golang-dev https://golang.org/cl/4826046
This commit is contained in:
parent
dec8009fe8
commit
a84abbe508
@ -595,9 +595,6 @@ agen(Node *n, Node *res)
|
||||
// i is in &n1 (if not constant)
|
||||
// w is width
|
||||
|
||||
if(w == 0)
|
||||
fatal("index is zero width");
|
||||
|
||||
// constant index
|
||||
if(isconst(nr, CTINT)) {
|
||||
if(isconst(nl, CTSTR))
|
||||
@ -683,7 +680,9 @@ agen(Node *n, Node *res)
|
||||
gmove(&n1, &n3);
|
||||
}
|
||||
|
||||
if(w == 1 || w == 2 || w == 4 || w == 8) {
|
||||
if(w == 0) {
|
||||
// nothing to do
|
||||
} else if(w == 1 || w == 2 || w == 4 || w == 8) {
|
||||
memset(&n4, 0, sizeof n4);
|
||||
n4.op = OADDR;
|
||||
n4.left = &n2;
|
||||
|
@ -7,6 +7,7 @@
|
||||
int thechar = '5';
|
||||
char* thestring = "arm";
|
||||
|
||||
vlong MAXWIDTH = (1LL<<32) - 1;
|
||||
|
||||
/*
|
||||
* go declares several platform-specific type aliases:
|
||||
|
@ -510,9 +510,6 @@ agen(Node *n, Node *res)
|
||||
regfree(&n4);
|
||||
}
|
||||
|
||||
if(w == 0)
|
||||
fatal("index is zero width");
|
||||
|
||||
// constant index
|
||||
if(isconst(nr, CTINT)) {
|
||||
if(isconst(nl, CTSTR))
|
||||
@ -600,7 +597,9 @@ agen(Node *n, Node *res)
|
||||
gmove(&n1, &n3);
|
||||
}
|
||||
|
||||
if(w == 1 || w == 2 || w == 4 || w == 8) {
|
||||
if(w == 0) {
|
||||
// nothing to do
|
||||
} else if(w == 1 || w == 2 || w == 4 || w == 8) {
|
||||
p1 = gins(ALEAQ, &n2, &n3);
|
||||
p1->from.scale = w;
|
||||
p1->from.index = p1->from.type;
|
||||
@ -608,7 +607,6 @@ agen(Node *n, Node *res)
|
||||
} else {
|
||||
ginscon(optoas(OMUL, t), w, &n2);
|
||||
gins(optoas(OADD, types[tptr]), &n2, &n3);
|
||||
gmove(&n3, res);
|
||||
}
|
||||
|
||||
indexdone:
|
||||
|
@ -7,6 +7,7 @@
|
||||
int thechar = '6';
|
||||
char* thestring = "amd64";
|
||||
|
||||
vlong MAXWIDTH = 1LL<<50;
|
||||
|
||||
/*
|
||||
* go declares several platform-specific type aliases:
|
||||
|
@ -562,9 +562,6 @@ agen(Node *n, Node *res)
|
||||
regfree(&n4);
|
||||
}
|
||||
|
||||
if(w == 0)
|
||||
fatal("index is zero width");
|
||||
|
||||
// constant index
|
||||
if(isconst(nr, CTINT)) {
|
||||
if(isconst(nl, CTSTR))
|
||||
@ -639,7 +636,9 @@ agen(Node *n, Node *res)
|
||||
gmove(&n1, &n3);
|
||||
}
|
||||
|
||||
if(w == 1 || w == 2 || w == 4 || w == 8) {
|
||||
if(w == 0) {
|
||||
// nothing to do
|
||||
} else if(w == 1 || w == 2 || w == 4 || w == 8) {
|
||||
p1 = gins(ALEAL, &n2, &n3);
|
||||
p1->from.scale = w;
|
||||
p1->from.index = p1->from.type;
|
||||
@ -648,7 +647,6 @@ agen(Node *n, Node *res)
|
||||
nodconst(&n1, types[TUINT32], w);
|
||||
gins(optoas(OMUL, types[TUINT32]), &n1, &n2);
|
||||
gins(optoas(OADD, types[tptr]), &n2, &n3);
|
||||
gmove(&n3, res);
|
||||
}
|
||||
|
||||
indexdone:
|
||||
|
@ -7,6 +7,7 @@
|
||||
int thechar = '8';
|
||||
char* thestring = "386";
|
||||
|
||||
vlong MAXWIDTH = (1LL<<32) - 1;
|
||||
|
||||
/*
|
||||
* go declares several platform-specific type aliases:
|
||||
|
@ -30,14 +30,18 @@ offmod(Type *t)
|
||||
o = 0;
|
||||
for(f=t->type; f!=T; f=f->down) {
|
||||
if(f->etype != TFIELD)
|
||||
fatal("widstruct: not TFIELD: %lT", f);
|
||||
fatal("offmod: not TFIELD: %lT", f);
|
||||
f->width = o;
|
||||
o += widthptr;
|
||||
if(o >= MAXWIDTH) {
|
||||
yyerror("interface too large");
|
||||
o = widthptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint32
|
||||
widstruct(Type *t, uint32 o, int flag)
|
||||
static vlong
|
||||
widstruct(Type *errtype, Type *t, vlong o, int flag)
|
||||
{
|
||||
Type *f;
|
||||
int32 w, maxalign;
|
||||
@ -69,6 +73,10 @@ widstruct(Type *t, uint32 o, int flag)
|
||||
f->nname->xoffset = o;
|
||||
}
|
||||
o += w;
|
||||
if(o >= MAXWIDTH) {
|
||||
yyerror("type %lT too large", errtype);
|
||||
o = 8; // small but nonzero
|
||||
}
|
||||
}
|
||||
// final width is rounded
|
||||
if(flag)
|
||||
@ -226,10 +234,7 @@ dowidth(Type *t)
|
||||
|
||||
dowidth(t->type);
|
||||
if(t->type->width != 0) {
|
||||
if(tptr == TPTR32)
|
||||
cap = ((uint32)-1) / t->type->width;
|
||||
else
|
||||
cap = ((uint64)-1) / t->type->width;
|
||||
cap = (MAXWIDTH-1) / t->type->width;
|
||||
if(t->bound > cap)
|
||||
yyerror("type %lT larger than address space", t);
|
||||
}
|
||||
@ -250,7 +255,7 @@ dowidth(Type *t)
|
||||
case TSTRUCT:
|
||||
if(t->funarg)
|
||||
fatal("dowidth fn struct %T", t);
|
||||
w = widstruct(t, 0, 1);
|
||||
w = widstruct(t, t, 0, 1);
|
||||
break;
|
||||
|
||||
case TFUNC:
|
||||
@ -268,9 +273,9 @@ dowidth(Type *t)
|
||||
// function is 3 cated structures;
|
||||
// compute their widths as side-effect.
|
||||
t1 = t->type;
|
||||
w = widstruct(*getthis(t1), 0, 0);
|
||||
w = widstruct(*getinarg(t1), w, widthptr);
|
||||
w = widstruct(*getoutarg(t1), w, widthptr);
|
||||
w = widstruct(t->type, *getthis(t1), 0, 0);
|
||||
w = widstruct(t->type, *getinarg(t1), w, widthptr);
|
||||
w = widstruct(t->type, *getoutarg(t1), w, widthptr);
|
||||
t1->argwid = w;
|
||||
if(w%widthptr)
|
||||
warn("bad type %T %d\n", t1, w);
|
||||
|
@ -43,9 +43,10 @@ enum
|
||||
AMEMWORD,
|
||||
|
||||
BADWIDTH = -1000000000,
|
||||
MAXWIDTH = 1<<30
|
||||
};
|
||||
|
||||
extern vlong MAXWIDTH;
|
||||
|
||||
/*
|
||||
* note this is the representation
|
||||
* of the compilers string literals,
|
||||
|
@ -20,7 +20,7 @@ runtime·makeslice(SliceType *t, int64 len, int64 cap, Slice ret)
|
||||
{
|
||||
if(len < 0 || (int32)len != len)
|
||||
runtime·panicstring("makeslice: len out of range");
|
||||
if(cap < len || (int32)cap != cap || cap > ((uintptr)-1) / t->elem->size)
|
||||
if(cap < len || (int32)cap != cap || t->elem->size > 0 && cap > ((uintptr)-1) / t->elem->size)
|
||||
runtime·panicstring("makeslice: cap out of range");
|
||||
|
||||
makeslice1(t, len, cap, &ret);
|
||||
|
@ -47,15 +47,6 @@ func bigcap() {
|
||||
g1 = make([]int, 10, big)
|
||||
}
|
||||
|
||||
const (
|
||||
addrBits = 8*uint(unsafe.Sizeof((*byte)(nil)))
|
||||
sh = addrBits/2 - 2
|
||||
)
|
||||
var g2 [][1<<sh][1<<sh]byte
|
||||
func overflow() {
|
||||
g2 = make([][1<<sh][1<<sh]byte, 64)
|
||||
}
|
||||
|
||||
var g3 map[int]int
|
||||
func badmapcap() {
|
||||
g3 = make(map[int]int, minus1)
|
||||
@ -74,6 +65,8 @@ func bigchancap() {
|
||||
g4 = make(chan int, big)
|
||||
}
|
||||
|
||||
const addrBits = unsafe.Sizeof((*byte)(nil))
|
||||
|
||||
var g5 chan [1<<15]byte
|
||||
func overflowchan() {
|
||||
if addrBits == 32 {
|
||||
@ -92,7 +85,6 @@ func main() {
|
||||
shouldfail(badcap, "badcap")
|
||||
shouldfail(badcap1, "badcap1")
|
||||
shouldfail(bigcap, "bigcap")
|
||||
shouldfail(overflow, "overflow")
|
||||
shouldfail(badmapcap, "badmapcap")
|
||||
shouldfail(bigmapcap, "bigmapcap")
|
||||
shouldfail(badchancap, "badchancap")
|
||||
|
19
test/fixedbugs/bug352.go
Normal file
19
test/fixedbugs/bug352.go
Normal file
@ -0,0 +1,19 @@
|
||||
// $G $D/$F.go && $L $F.$A && ./$A.out || echo BUG: bug352
|
||||
|
||||
// Copyright 2011 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.
|
||||
|
||||
package main
|
||||
|
||||
var x [10][0]byte
|
||||
var y = make([]struct{}, 10)
|
||||
|
||||
func main() {
|
||||
if &x[1] != &x[2] {
|
||||
println("BUG: bug352 [0]byte")
|
||||
}
|
||||
if &y[1] != &y[2] {
|
||||
println("BUG: bug352 struct{}")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user