diff --git a/src/cmd/gc/align.c b/src/cmd/gc/align.c index c4facf1be01..460358df18a 100644 --- a/src/cmd/gc/align.c +++ b/src/cmd/gc/align.c @@ -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; diff --git a/src/cmd/gc/builtin.c.boot b/src/cmd/gc/builtin.c.boot index 94efa412bf4..1e7a14947b6 100644 --- a/src/cmd/gc/builtin.c.boot +++ b/src/cmd/gc/builtin.c.boot @@ -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" diff --git a/src/cmd/gc/runtime.go b/src/cmd/gc/runtime.go index e08e1f60174..392de17a00a 100644 --- a/src/cmd/gc/runtime.go +++ b/src/cmd/gc/runtime.go @@ -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) diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c index ae1d13d17a5..707546b1095 100644 --- a/src/cmd/gc/typecheck.c +++ b/src/cmd/gc/typecheck.c @@ -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]) { diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index 951496e604f..a79c75131f0 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -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: diff --git a/src/pkg/runtime/chan.c b/src/pkg/runtime/chan.c index 57931590624..08cd75a6e53 100644 --- a/src/pkg/runtime/chan.c +++ b/src/pkg/runtime/chan.c @@ -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); diff --git a/src/pkg/runtime/hashmap.c b/src/pkg/runtime/hashmap.c index f27264b6826..9b039121bb1 100644 --- a/src/pkg/runtime/hashmap.c +++ b/src/pkg/runtime/hashmap.c @@ -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); diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h index ff4f463b37c..4c9f52e85c0 100644 --- a/src/pkg/runtime/runtime.h +++ b/src/pkg/runtime/runtime.h @@ -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*); diff --git a/src/pkg/runtime/slice.c b/src/pkg/runtime/slice.c index c3c079c670a..d967b1669b9 100644 --- a/src/pkg/runtime/slice.c +++ b/src/pkg/runtime/slice.c @@ -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); } } diff --git a/test/fixedbugs/bug273.go b/test/fixedbugs/bug273.go new file mode 100644 index 00000000000..ff8f1c6af3a --- /dev/null +++ b/test/fixedbugs/bug273.go @@ -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<