aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2012-02-08 06:18:41 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2012-02-08 06:18:41 +0000
commit047cff816d1457fa3894b7cd2a61752f669704c7 (patch)
tree0079e628bdcefa4ba284ae32a63173c4c470d869
parent7f57843fbebc7b50cfad7cc5bd3459a2d1077035 (diff)
downloadgcc-047cff816d1457fa3894b7cd2a61752f669704c7.zip
gcc-047cff816d1457fa3894b7cd2a61752f669704c7.tar.gz
gcc-047cff816d1457fa3894b7cd2a61752f669704c7.tar.bz2
compiler, runtime: Check make int64 args for overflow.
From-SVN: r183994
-rw-r--r--gcc/go/gofrontend/expressions.cc32
-rw-r--r--gcc/go/gofrontend/runtime.def7
-rw-r--r--libgo/runtime/chan.c6
-rw-r--r--libgo/runtime/go-make-slice.c24
-rw-r--r--libgo/runtime/go-new-map.c14
5 files changed, 77 insertions, 6 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index f906b22..395a375 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -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();
diff --git a/gcc/go/gofrontend/runtime.def b/gcc/go/gofrontend/runtime.def
index 57d5090..7dda539 100644
--- a/gcc/go/gofrontend/runtime.def
+++ b/gcc/go/gofrontend/runtime.def
@@ -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))
diff --git a/libgo/runtime/chan.c b/libgo/runtime/chan.c
index a246992..4fc2d60 100644
--- a/libgo/runtime/chan.c
+++ b/libgo/runtime/chan.c
@@ -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,
diff --git a/libgo/runtime/go-make-slice.c b/libgo/runtime/go-make-slice.c
index 765e7c0..42b412c 100644
--- a/libgo/runtime/go-make-slice.c
+++ b/libgo/runtime/go-make-slice.c
@@ -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);
+}
diff --git a/libgo/runtime/go-new-map.c b/libgo/runtime/go-new-map.c
index 288e188..eef71dd 100644
--- a/libgo/runtime/go-new-map.c
+++ b/libgo/runtime/go-new-map.c
@@ -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);
+}