mirror of
https://github.com/golang/go
synced 2024-11-22 01:34:41 -07:00
gc: be pickier about slice, chan, array, and map sizes
Fixes #589. R=ken2 CC=golang-dev https://golang.org/cl/1032044
This commit is contained in:
parent
97576673bd
commit
6361f52fc4
@ -96,7 +96,7 @@ void
|
||||
dowidth(Type *t)
|
||||
{
|
||||
int32 et;
|
||||
uint32 w;
|
||||
int64 w;
|
||||
int lno;
|
||||
Type *t1;
|
||||
|
||||
@ -222,7 +222,15 @@ dowidth(Type *t)
|
||||
if(t->type == T)
|
||||
break;
|
||||
if(t->bound >= 0) {
|
||||
uint64 cap;
|
||||
|
||||
dowidth(t->type);
|
||||
if(tptr == TPTR32)
|
||||
cap = ((uint32)-1) / t->type->width;
|
||||
else
|
||||
cap = ((uint64)-1) / t->type->width;
|
||||
if(t->bound > cap)
|
||||
yyerror("type %lT larger than address space", t);
|
||||
w = t->bound * t->type->width;
|
||||
if(w == 0)
|
||||
w = maxround;
|
||||
|
@ -33,47 +33,47 @@ char *runtimeimport =
|
||||
"func \"\".stringiter (? string, ? int) int\n"
|
||||
"func \"\".stringiter2 (? string, ? int) (retk int, retv int)\n"
|
||||
"func \"\".slicecopy (to any, fr any, wid uint32) int\n"
|
||||
"func \"\".ifaceI2E (iface any) (ret any)\n"
|
||||
"func \"\".ifaceE2I (typ *uint8, iface any) (ret any)\n"
|
||||
"func \"\".ifaceT2E (typ *uint8, elem any) (ret any)\n"
|
||||
"func \"\".ifaceE2T (typ *uint8, elem any) (ret any)\n"
|
||||
"func \"\".ifaceI2E (iface any) any\n"
|
||||
"func \"\".ifaceE2I (typ *uint8, iface any) any\n"
|
||||
"func \"\".ifaceT2E (typ *uint8, elem any) any\n"
|
||||
"func \"\".ifaceE2T (typ *uint8, elem any) any\n"
|
||||
"func \"\".ifaceE2I2 (typ *uint8, iface any) (ret any, ok bool)\n"
|
||||
"func \"\".ifaceE2T2 (typ *uint8, elem any) (ret any, ok bool)\n"
|
||||
"func \"\".ifaceT2I (typ1 *uint8, typ2 *uint8, elem any) (ret any)\n"
|
||||
"func \"\".ifaceI2T (typ *uint8, iface any) (ret any)\n"
|
||||
"func \"\".ifaceT2I (typ1 *uint8, typ2 *uint8, elem any) any\n"
|
||||
"func \"\".ifaceI2T (typ *uint8, iface any) any\n"
|
||||
"func \"\".ifaceI2T2 (typ *uint8, iface any) (ret any, ok bool)\n"
|
||||
"func \"\".ifaceI2I (typ *uint8, iface any) (ret any)\n"
|
||||
"func \"\".ifaceI2Ix (typ *uint8, iface any) (ret any)\n"
|
||||
"func \"\".ifaceI2I (typ *uint8, iface any) any\n"
|
||||
"func \"\".ifaceI2Ix (typ *uint8, iface any) any\n"
|
||||
"func \"\".ifaceI2I2 (typ *uint8, iface any) (ret any, ok bool)\n"
|
||||
"func \"\".ifaceeq (i1 any, i2 any) (ret bool)\n"
|
||||
"func \"\".efaceeq (i1 any, i2 any) (ret bool)\n"
|
||||
"func \"\".ifacethash (i1 any) (ret uint32)\n"
|
||||
"func \"\".efacethash (i1 any) (ret uint32)\n"
|
||||
"func \"\".makemap (key *uint8, val *uint8, hint int) (hmap map[any] any)\n"
|
||||
"func \"\".mapaccess1 (hmap map[any] any, key any) (val any)\n"
|
||||
"func \"\".ifaceeq (i1 any, i2 any) bool\n"
|
||||
"func \"\".efaceeq (i1 any, i2 any) bool\n"
|
||||
"func \"\".ifacethash (i1 any) uint32\n"
|
||||
"func \"\".efacethash (i1 any) uint32\n"
|
||||
"func \"\".makemap (key *uint8, val *uint8, hint int64) map[any] any\n"
|
||||
"func \"\".mapaccess1 (hmap map[any] any, key any) any\n"
|
||||
"func \"\".mapaccess2 (hmap map[any] any, key any) (val any, pres bool)\n"
|
||||
"func \"\".mapassign1 (hmap map[any] any, key any, val any)\n"
|
||||
"func \"\".mapassign2 (hmap map[any] any, key any, val any, pres bool)\n"
|
||||
"func \"\".mapiterinit (hmap map[any] any, hiter *any)\n"
|
||||
"func \"\".mapiternext (hiter *any)\n"
|
||||
"func \"\".mapiter1 (hiter *any) (key any)\n"
|
||||
"func \"\".mapiter1 (hiter *any) any\n"
|
||||
"func \"\".mapiter2 (hiter *any) (key any, val any)\n"
|
||||
"func \"\".makechan (elem *uint8, hint int) (hchan chan any)\n"
|
||||
"func \"\".chanrecv1 (hchan <-chan any) (elem any)\n"
|
||||
"func \"\".makechan (elem *uint8, hint int64) chan any\n"
|
||||
"func \"\".chanrecv1 (hchan <-chan any) any\n"
|
||||
"func \"\".chanrecv2 (hchan <-chan any) (elem any, pres bool)\n"
|
||||
"func \"\".chansend1 (hchan chan<- any, elem any)\n"
|
||||
"func \"\".chansend2 (hchan chan<- any, elem any) (pres bool)\n"
|
||||
"func \"\".chansend2 (hchan chan<- any, elem any) bool\n"
|
||||
"func \"\".closechan (hchan any)\n"
|
||||
"func \"\".closedchan (hchan any) bool\n"
|
||||
"func \"\".newselect (size int) (sel *uint8)\n"
|
||||
"func \"\".selectsend (sel *uint8, hchan chan<- any, elem any) (selected bool)\n"
|
||||
"func \"\".selectrecv (sel *uint8, hchan <-chan any, elem *any) (selected bool)\n"
|
||||
"func \"\".selectdefault (sel *uint8) (selected bool)\n"
|
||||
"func \"\".newselect (size int) *uint8\n"
|
||||
"func \"\".selectsend (sel *uint8, hchan chan<- any, elem any) bool\n"
|
||||
"func \"\".selectrecv (sel *uint8, hchan <-chan any, elem *any) bool\n"
|
||||
"func \"\".selectdefault (sel *uint8) bool\n"
|
||||
"func \"\".selectgo (sel *uint8)\n"
|
||||
"func \"\".makeslice (typ *uint8, nel int, cap int) (ary []any)\n"
|
||||
"func \"\".sliceslice1 (old []any, lb int, width int) (ary []any)\n"
|
||||
"func \"\".sliceslice (old []any, lb int, hb int, width int) (ary []any)\n"
|
||||
"func \"\".slicearray (old *any, nel int, lb int, hb int, width int) (ary []any)\n"
|
||||
"func \"\".makeslice (typ *uint8, nel int64, cap int64) []any\n"
|
||||
"func \"\".sliceslice1 (old []any, lb int, width int) []any\n"
|
||||
"func \"\".sliceslice (old []any, lb int, hb int, width int) []any\n"
|
||||
"func \"\".slicearray (old *any, nel int, lb int, hb int, width int) []any\n"
|
||||
"func \"\".closure ()\n"
|
||||
"func \"\".int64div (? int64, ? int64) int64\n"
|
||||
"func \"\".uint64div (? uint64, ? uint64) uint64\n"
|
||||
@ -81,7 +81,7 @@ char *runtimeimport =
|
||||
"func \"\".uint64mod (? uint64, ? uint64) uint64\n"
|
||||
"func \"\".float64toint64 (? float64) int64\n"
|
||||
"func \"\".int64tofloat64 (? int64) float64\n"
|
||||
"func \"\".complex128div (num complex128, den complex128) (quo complex128)\n"
|
||||
"func \"\".complex128div (num complex128, den complex128) complex128\n"
|
||||
"\n"
|
||||
"$$\n";
|
||||
char *unsafeimport =
|
||||
@ -90,9 +90,9 @@ char *unsafeimport =
|
||||
"func \"\".Offsetof (? any) int\n"
|
||||
"func \"\".Sizeof (? any) int\n"
|
||||
"func \"\".Alignof (? any) int\n"
|
||||
"func \"\".Typeof (i interface { }) (typ interface { })\n"
|
||||
"func \"\".Typeof (i interface { }) interface { }\n"
|
||||
"func \"\".Reflect (i interface { }) (typ interface { }, addr \"\".Pointer)\n"
|
||||
"func \"\".Unreflect (typ interface { }, addr \"\".Pointer) (ret interface { })\n"
|
||||
"func \"\".Unreflect (typ interface { }, addr \"\".Pointer) interface { }\n"
|
||||
"func \"\".New (typ interface { }) \"\".Pointer\n"
|
||||
"func \"\".NewArray (typ interface { }, n int) \"\".Pointer\n"
|
||||
"\n"
|
||||
|
@ -65,7 +65,7 @@ func ifacethash(i1 any) (ret uint32)
|
||||
func efacethash(i1 any) (ret uint32)
|
||||
|
||||
// *byte is really *runtime.Type
|
||||
func makemap(key, val *byte, hint int) (hmap map[any]any)
|
||||
func makemap(key, val *byte, hint int64) (hmap map[any]any)
|
||||
func mapaccess1(hmap map[any]any, key any) (val any)
|
||||
func mapaccess2(hmap map[any]any, key any) (val any, pres bool)
|
||||
func mapassign1(hmap map[any]any, key any, val any)
|
||||
@ -76,7 +76,7 @@ func mapiter1(hiter *any) (key any)
|
||||
func mapiter2(hiter *any) (key any, val any)
|
||||
|
||||
// *byte is really *runtime.Type
|
||||
func makechan(elem *byte, hint int) (hchan chan any)
|
||||
func makechan(elem *byte, hint int64) (hchan chan any)
|
||||
func chanrecv1(hchan <-chan any) (elem any)
|
||||
func chanrecv2(hchan <-chan any) (elem any, pres bool)
|
||||
func chansend1(hchan chan<- any, elem any)
|
||||
@ -90,7 +90,7 @@ func selectrecv(sel *byte, hchan <-chan any, elem *any) (selected bool)
|
||||
func selectdefault(sel *byte) (selected bool)
|
||||
func selectgo(sel *byte)
|
||||
|
||||
func makeslice(typ *byte, nel int, cap int) (ary []any)
|
||||
func makeslice(typ *byte, nel int64, cap int64) (ary []any)
|
||||
func sliceslice1(old []any, lb int, width int) (ary []any)
|
||||
func sliceslice(old []any, lb int, hb int, width int) (ary []any)
|
||||
func slicearray(old *any, nel int, lb int, hb int, width int) (ary []any)
|
||||
|
@ -929,13 +929,13 @@ reswitch:
|
||||
l = args->n;
|
||||
args = args->next;
|
||||
typecheck(&l, Erv);
|
||||
defaultlit(&l, types[TUINT]);
|
||||
defaultlit(&l, types[TINT]);
|
||||
r = N;
|
||||
if(args != nil) {
|
||||
r = args->n;
|
||||
args = args->next;
|
||||
typecheck(&r, Erv);
|
||||
defaultlit(&r, types[TUINT]);
|
||||
defaultlit(&r, types[TINT]);
|
||||
}
|
||||
if(l->type == T || (r && r->type == T))
|
||||
goto error;
|
||||
@ -947,8 +947,6 @@ reswitch:
|
||||
yyerror("non-integer cap argument to make(%T)", t);
|
||||
goto error;
|
||||
}
|
||||
if(r == N)
|
||||
r = nodintconst(0);
|
||||
n->left = l;
|
||||
n->right = r;
|
||||
n->op = OMAKESLICE;
|
||||
@ -959,7 +957,7 @@ reswitch:
|
||||
l = args->n;
|
||||
args = args->next;
|
||||
typecheck(&l, Erv);
|
||||
defaultlit(&l, types[TUINT]);
|
||||
defaultlit(&l, types[TINT]);
|
||||
if(l->type == T)
|
||||
goto error;
|
||||
if(!isint[l->type->etype]) {
|
||||
@ -978,7 +976,7 @@ reswitch:
|
||||
l = args->n;
|
||||
args = args->next;
|
||||
typecheck(&l, Erv);
|
||||
defaultlit(&l, types[TUINT]);
|
||||
defaultlit(&l, types[TINT]);
|
||||
if(l->type == T)
|
||||
goto error;
|
||||
if(!isint[l->type->etype]) {
|
||||
|
@ -1138,7 +1138,7 @@ walkexpr(Node **np, NodeList **init)
|
||||
case OMAKECHAN:
|
||||
n = mkcall1(chanfn("makechan", 1, n->type), n->type, init,
|
||||
typename(n->type->type),
|
||||
conv(n->left, types[TINT]));
|
||||
conv(n->left, types[TINT64]));
|
||||
goto ret;
|
||||
|
||||
case OMAKEMAP:
|
||||
@ -1151,18 +1151,22 @@ walkexpr(Node **np, NodeList **init)
|
||||
n = mkcall1(fn, n->type, init,
|
||||
typename(t->down), // key type
|
||||
typename(t->type), // value type
|
||||
conv(n->left, types[TINT]));
|
||||
conv(n->left, types[TINT64]));
|
||||
goto ret;
|
||||
|
||||
case OMAKESLICE:
|
||||
// makeslice(nel int, max int, width int) (ary []any)
|
||||
// makeslice(t *Type, nel int64, max int64) (ary []any)
|
||||
l = n->left;
|
||||
r = n->right;
|
||||
if(r == nil)
|
||||
l = r = safeexpr(l, init);
|
||||
t = n->type;
|
||||
fn = syslook("makeslice", 1);
|
||||
argtype(fn, t->type); // any-1
|
||||
n = mkcall1(fn, n->type, init,
|
||||
typename(n->type),
|
||||
conv(n->left, types[TINT]),
|
||||
conv(n->right, types[TINT]));
|
||||
conv(l, types[TINT64]),
|
||||
conv(r, types[TINT64]));
|
||||
goto ret;
|
||||
|
||||
case ORUNESTR:
|
||||
|
@ -90,11 +90,14 @@ static uint32 fastrand2(void);
|
||||
static void destroychan(Hchan*);
|
||||
|
||||
Hchan*
|
||||
makechan(Type *elem, uint32 hint)
|
||||
makechan(Type *elem, int64 hint)
|
||||
{
|
||||
Hchan *c;
|
||||
int32 i;
|
||||
|
||||
if(hint < 0 || (int32)hint != hint || hint > ((uintptr)-1) / elem->size)
|
||||
panicstring("makechan: size out of range");
|
||||
|
||||
if(elem->alg >= nelem(algarray)) {
|
||||
printf("chan(alg=%d)\n", elem->alg);
|
||||
throw("runtime.makechan: unsupported elem type");
|
||||
@ -141,9 +144,9 @@ destroychan(Hchan *c)
|
||||
}
|
||||
|
||||
|
||||
// makechan(elemsize uint32, elemalg uint32, hint uint32) (hchan *chan any);
|
||||
// makechan(elem *Type, hint int64) (hchan *chan any);
|
||||
void
|
||||
·makechan(Type *elem, uint32 hint, Hchan *ret)
|
||||
·makechan(Type *elem, int64 hint, Hchan *ret)
|
||||
{
|
||||
ret = makechan(elem, hint);
|
||||
FLUSH(&ret);
|
||||
|
@ -667,11 +667,14 @@ static int32 debug = 0;
|
||||
|
||||
// makemap(key, val *Type, hint uint32) (hmap *map[any]any);
|
||||
Hmap*
|
||||
makemap(Type *key, Type *val, uint32 hint)
|
||||
makemap(Type *key, Type *val, int64 hint)
|
||||
{
|
||||
Hmap *h;
|
||||
int32 keyalg, valalg, keysize, valsize;
|
||||
|
||||
if(hint < 0 || (int32)hint != hint)
|
||||
panicstring("makemap: size out of range");
|
||||
|
||||
keyalg = key->alg;
|
||||
valalg = val->alg;
|
||||
keysize = key->size;
|
||||
@ -731,9 +734,9 @@ makemap(Type *key, Type *val, uint32 hint)
|
||||
return h;
|
||||
}
|
||||
|
||||
// makemap(key, val *Type, hint uint32) (hmap *map[any]any);
|
||||
// makemap(key, val *Type, hint int64) (hmap *map[any]any);
|
||||
void
|
||||
·makemap(Type *key, Type *val, uint32 hint, Hmap *ret)
|
||||
·makemap(Type *key, Type *val, int64 hint, Hmap *ret)
|
||||
{
|
||||
ret = makemap(key, val, hint);
|
||||
FLUSH(&ret);
|
||||
|
@ -577,9 +577,9 @@ struct hash_iter* mapiterinit(Hmap*);
|
||||
void mapiternext(struct hash_iter*);
|
||||
bool mapiterkey(struct hash_iter*, void*);
|
||||
void mapiterkeyvalue(struct hash_iter*, void*, void*);
|
||||
Hmap* makemap(Type*, Type*, uint32);
|
||||
Hmap* makemap(Type*, Type*, int64);
|
||||
|
||||
Hchan* makechan(Type*, uint32);
|
||||
Hchan* makechan(Type*, int64);
|
||||
void chansend(Hchan*, void*, bool*);
|
||||
void chanrecv(Hchan*, void*, bool*);
|
||||
void chanclose(Hchan*);
|
||||
|
@ -9,17 +9,20 @@
|
||||
static int32 debug = 0;
|
||||
|
||||
// see also unsafe·NewArray
|
||||
// makeslice(typ *Type, nel int, cap int) (ary []any);
|
||||
// makeslice(typ *Type, len, cap int64) (ary []any);
|
||||
void
|
||||
·makeslice(SliceType *t, uint32 nel, uint32 cap, Slice ret)
|
||||
·makeslice(SliceType *t, int64 len, int64 cap, Slice ret)
|
||||
{
|
||||
uint64 size;
|
||||
uintptr size;
|
||||
|
||||
if(len < 0 || (int32)len != len)
|
||||
panicstring("makeslice: len out of range");
|
||||
if(cap < len || (int32)cap != cap || cap > ((uintptr)-1) / t->elem->size)
|
||||
panicstring("makeslice: cap out of range");
|
||||
|
||||
if(cap < nel)
|
||||
cap = nel;
|
||||
size = cap*t->elem->size;
|
||||
|
||||
ret.len = nel;
|
||||
ret.len = len;
|
||||
ret.cap = cap;
|
||||
|
||||
if((t->elem->kind&KindNoPointers))
|
||||
@ -30,8 +33,8 @@ void
|
||||
FLUSH(&ret);
|
||||
|
||||
if(debug) {
|
||||
printf("makeslice(%S, %d, %d); ret=",
|
||||
*t->string, nel, cap);
|
||||
printf("makeslice(%S, %D, %D); ret=",
|
||||
*t->string, len, cap);
|
||||
·printslice(ret);
|
||||
}
|
||||
}
|
||||
|
95
test/fixedbugs/bug273.go
Normal file
95
test/fixedbugs/bug273.go
Normal file
@ -0,0 +1,95 @@
|
||||
// $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=589
|
||||
|
||||
package main
|
||||
|
||||
import "unsafe"
|
||||
|
||||
var bug = false
|
||||
|
||||
var minus1 = -1
|
||||
var big int64 = 10 | 1<<32
|
||||
|
||||
func shouldfail(f func(), desc string) {
|
||||
defer func() { recover() }()
|
||||
f()
|
||||
if !bug {
|
||||
println("BUG")
|
||||
bug = true
|
||||
}
|
||||
println("didn't crash: ", desc)
|
||||
}
|
||||
|
||||
func badlen() {
|
||||
_ = make([]int, minus1)
|
||||
}
|
||||
|
||||
func biglen() {
|
||||
_ = make([]int, big)
|
||||
}
|
||||
|
||||
func badcap() {
|
||||
_ = make([]int, 10, minus1)
|
||||
}
|
||||
|
||||
func badcap1() {
|
||||
_ = make([]int, 10, 5)
|
||||
}
|
||||
|
||||
func bigcap() {
|
||||
_ = make([]int, 10, big)
|
||||
}
|
||||
|
||||
const (
|
||||
addrBits = 8*uint(unsafe.Sizeof((*byte)(nil)))
|
||||
sh = addrBits/2 - 2
|
||||
)
|
||||
func overflow() {
|
||||
_ = make([][1<<sh][1<<sh]byte, 64)
|
||||
}
|
||||
|
||||
func badmapcap() {
|
||||
_ = make(map[int]int, minus1)
|
||||
}
|
||||
|
||||
func bigmapcap() {
|
||||
_ = make(map[int]int, big)
|
||||
}
|
||||
|
||||
func badchancap() {
|
||||
_ = make(chan int, minus1)
|
||||
}
|
||||
|
||||
func bigchancap() {
|
||||
_ = make(chan int, big)
|
||||
}
|
||||
|
||||
func overflowchan() {
|
||||
if addrBits == 32 {
|
||||
_ = make(chan [1<<15]byte, 1<<20)
|
||||
} else {
|
||||
// cannot overflow on 64-bit, because
|
||||
// int is 32 bits and max chan value size
|
||||
// in the implementation is 64 kB.
|
||||
panic(1)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
shouldfail(badlen, "badlen")
|
||||
shouldfail(biglen, "biglen")
|
||||
shouldfail(badcap, "badcap")
|
||||
shouldfail(badcap1, "badcap1")
|
||||
shouldfail(bigcap, "bigcap")
|
||||
shouldfail(overflow, "overflow")
|
||||
shouldfail(badmapcap, "badmapcap")
|
||||
shouldfail(bigmapcap, "bigmapcap")
|
||||
shouldfail(badchancap, "badchancap")
|
||||
shouldfail(bigchancap, "bigchancap")
|
||||
shouldfail(overflowchan, "overflowchan")
|
||||
}
|
Loading…
Reference in New Issue
Block a user