diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-02-08 06:18:41 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-02-08 06:18:41 +0000 |
commit | 047cff816d1457fa3894b7cd2a61752f669704c7 (patch) | |
tree | 0079e628bdcefa4ba284ae32a63173c4c470d869 /gcc/go/gofrontend/expressions.cc | |
parent | 7f57843fbebc7b50cfad7cc5bd3459a2d1077035 (diff) | |
download | gcc-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/go/gofrontend/expressions.cc')
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 32 |
1 files changed, 26 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(); |