compiler, runtime: Check make int64 args for overflow.

From-SVN: r183994
This commit is contained in:
Ian Lance Taylor 2012-02-08 06:18:41 +00:00
parent 7f57843fbe
commit 047cff816d
5 changed files with 77 additions and 6 deletions

View File

@ -7744,6 +7744,10 @@ Builtin_call_expression::lower_make()
return Expression::make_error(this->location());
}
bool have_big_args = false;
Type* uintptr_type = Type::lookup_integer_type("uintptr");
int uintptr_bits = uintptr_type->integer_type()->bits();
++parg;
Expression* len_arg;
if (parg == args->end())
@ -7767,6 +7771,9 @@ Builtin_call_expression::lower_make()
this->report_error(_("bad size for make"));
return Expression::make_error(this->location());
}
if (len_arg->type()->integer_type() != NULL
&& len_arg->type()->integer_type()->bits() > uintptr_bits)
have_big_args = true;
++parg;
}
@ -7779,6 +7786,9 @@ Builtin_call_expression::lower_make()
this->report_error(_("bad capacity when making slice"));
return Expression::make_error(this->location());
}
if (cap_arg->type()->integer_type() != NULL
&& cap_arg->type()->integer_type()->bits() > uintptr_bits)
have_big_args = true;
++parg;
}
@ -7801,16 +7811,26 @@ Builtin_call_expression::lower_make()
if (is_slice)
{
if (cap_arg == NULL)
call = Runtime::make_call(Runtime::MAKESLICE1, loc, 2, type_arg,
len_arg);
call = Runtime::make_call((have_big_args
? Runtime::MAKESLICE1BIG
: Runtime::MAKESLICE1),
loc, 2, type_arg, len_arg);
else
call = Runtime::make_call(Runtime::MAKESLICE2, loc, 3, type_arg,
len_arg, cap_arg);
call = Runtime::make_call((have_big_args
? Runtime::MAKESLICE2BIG
: Runtime::MAKESLICE2),
loc, 3, type_arg, len_arg, cap_arg);
}
else if (is_map)
call = Runtime::make_call(Runtime::MAKEMAP, loc, 2, type_arg, len_arg);
call = Runtime::make_call((have_big_args
? Runtime::MAKEMAPBIG
: Runtime::MAKEMAP),
loc, 2, type_arg, len_arg);
else if (is_chan)
call = Runtime::make_call(Runtime::MAKECHAN, loc, 2, type_arg, len_arg);
call = Runtime::make_call((have_big_args
? Runtime::MAKECHANBIG
: Runtime::MAKECHAN),
loc, 2, type_arg, len_arg);
else
go_unreachable();

View File

@ -72,10 +72,16 @@ DEF_GO_RUNTIME(STRING_TO_INT_ARRAY, "__go_string_to_int_array",
DEF_GO_RUNTIME(MAKESLICE1, "__go_make_slice1", P2(TYPE, UINTPTR), R1(SLICE))
DEF_GO_RUNTIME(MAKESLICE2, "__go_make_slice2", P3(TYPE, UINTPTR, UINTPTR),
R1(SLICE))
DEF_GO_RUNTIME(MAKESLICE1BIG, "__go_make_slice1_big", P2(TYPE, UINT64),
R1(SLICE))
DEF_GO_RUNTIME(MAKESLICE2BIG, "__go_make_slice2_big", P3(TYPE, UINT64, UINT64),
R1(SLICE))
// Make a map.
DEF_GO_RUNTIME(MAKEMAP, "__go_new_map", P2(MAPDESCRIPTOR, UINTPTR), R1(MAP))
DEF_GO_RUNTIME(MAKEMAPBIG, "__go_new_map_big", P2(MAPDESCRIPTOR, UINT64),
R1(MAP))
// Build a map from a composite literal.
DEF_GO_RUNTIME(CONSTRUCT_MAP, "__go_construct_map",
@ -116,6 +122,7 @@ DEF_GO_RUNTIME(MAPITERNEXT, "runtime.mapiternext", P1(MAPITER), R0())
// Make a channel.
DEF_GO_RUNTIME(MAKECHAN, "__go_new_channel", P2(TYPE, UINTPTR), R1(CHAN))
DEF_GO_RUNTIME(MAKECHANBIG, "__go_new_channel_big", P2(TYPE, UINT64), R1(CHAN))
// Get the length of a channel (the number of unread values).
DEF_GO_RUNTIME(CHAN_LEN, "__go_chan_len", P1(CHAN), R1(INT))

View File

@ -130,6 +130,12 @@ __go_new_channel(ChanType *t, uintptr hint)
return runtime_makechan_c(t, hint);
}
Hchan*
__go_new_channel_big(ChanType *t, uint64 hint)
{
return runtime_makechan_c(t, hint);
}
/*
* generic single channel send/recv
* if the bool pointer is nil,

View File

@ -57,3 +57,27 @@ __go_make_slice1 (const struct __go_type_descriptor *td, uintptr_t len)
{
return __go_make_slice2 (td, len, len);
}
struct __go_open_array
__go_make_slice2_big (const struct __go_type_descriptor *td, uint64_t len,
uint64_t cap)
{
uintptr_t slen;
uintptr_t scap;
slen = (uintptr_t) len;
if ((uint64_t) slen != len)
runtime_panicstring ("makeslice: len out of range");
scap = (uintptr_t) cap;
if ((uint64_t) scap != cap)
runtime_panicstring ("makeslice: cap out of range");
return __go_make_slice2 (td, slen, scap);
}
struct __go_open_array
__go_make_slice1_big (const struct __go_type_descriptor *td, uint64_t len)
{
return __go_make_slice2_big (td, len, len);
}

View File

@ -125,3 +125,17 @@ __go_new_map (const struct __go_map_descriptor *descriptor, uintptr_t entries)
__builtin_memset (ret->__buckets, 0, entries * sizeof (void *));
return ret;
}
/* Allocate a new map when the argument to make is a large type. */
struct __go_map *
__go_new_map_big (const struct __go_map_descriptor *descriptor,
uint64_t entries)
{
uintptr_t sentries;
sentries = (uintptr_t) entries;
if ((uint64_t) sentries != entries)
runtime_panicstring ("map size out of range");
return __go_new_map (descriptor, sentries);
}