mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-11 13:01:20 +08:00
compiler, runtime: Check make int64 args for overflow.
From-SVN: r183994
This commit is contained in:
parent
7f57843fbe
commit
047cff816d
@ -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();
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user