aboutsummaryrefslogtreecommitdiff
path: root/gcc/go/gofrontend/expressions.cc
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/go/gofrontend/expressions.cc
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/go/gofrontend/expressions.cc')
-rw-r--r--gcc/go/gofrontend/expressions.cc32
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();