aboutsummaryrefslogtreecommitdiff
path: root/gcc
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 /gcc
parent7f57843fbebc7b50cfad7cc5bd3459a2d1077035 (diff)
downloadgcc-047cff816d1457fa3894b7cd2a61752f669704c7.zip
gcc-047cff816d1457fa3894b7cd2a61752f669704c7.tar.gz
gcc-047cff816d1457fa3894b7cd2a61752f669704c7.tar.bz2
compiler, runtime: Check make int64 args for overflow.
From-SVN: r183994
Diffstat (limited to 'gcc')
-rw-r--r--gcc/go/gofrontend/expressions.cc32
-rw-r--r--gcc/go/gofrontend/runtime.def7
2 files changed, 33 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))