aboutsummaryrefslogtreecommitdiff
path: root/gcc/go/gofrontend/expressions.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2017-01-14 00:05:42 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2017-01-14 00:05:42 +0000
commitc2047754c300b68c05d65faa8dc2925fe67b71b4 (patch)
treee183ae81a1f48a02945cb6de463a70c5be1b06f6 /gcc/go/gofrontend/expressions.cc
parent829afb8f05602bb31c9c597b24df7377fed4f059 (diff)
downloadgcc-c2047754c300b68c05d65faa8dc2925fe67b71b4.zip
gcc-c2047754c300b68c05d65faa8dc2925fe67b71b4.tar.gz
gcc-c2047754c300b68c05d65faa8dc2925fe67b71b4.tar.bz2
libgo: update to Go 1.8 release candidate 1
Compiler changes: * Change map assignment to use mapassign and assign value directly. * Change string iteration to use decoderune, faster for ASCII strings. * Change makeslice to take int, and use makeslice64 for larger values. * Add new noverflow field to hmap struct used for maps. Unresolved problems, to be fixed later: * Commented out test in go/types/sizes_test.go that doesn't compile. * Commented out reflect.TestStructOf test for padding after zero-sized field. Reviewed-on: https://go-review.googlesource.com/35231 gotools/: Updates for Go 1.8rc1. * Makefile.am (go_cmd_go_files): Add bug.go. (s-zdefaultcc): Write defaultPkgConfig. * Makefile.in: Rebuild. From-SVN: r244456
Diffstat (limited to 'gcc/go/gofrontend/expressions.cc')
-rw-r--r--gcc/go/gofrontend/expressions.cc36
1 files changed, 28 insertions, 8 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index fe4d07b..8006888 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -7091,7 +7091,7 @@ class Builtin_call_expression : public Call_expression
Expression* flatten_append(Gogo*, Named_object*, Statement_inserter*);
bool
- check_int_value(Expression*, bool is_length);
+ check_int_value(Expression*, bool is_length, bool* small);
// A pointer back to the general IR structure. This avoids a global
// variable, or passing it around everywhere.
@@ -7462,6 +7462,7 @@ Builtin_call_expression::lower_make(Statement_inserter* inserter)
++parg;
Expression* len_arg;
+ bool len_small = false;
if (parg == args->end())
{
if (is_slice)
@@ -7475,17 +7476,18 @@ Builtin_call_expression::lower_make(Statement_inserter* inserter)
{
len_arg = *parg;
len_arg->determine_type(&int_context);
- if (!this->check_int_value(len_arg, true))
+ if (!this->check_int_value(len_arg, true, &len_small))
return Expression::make_error(this->location());
++parg;
}
Expression* cap_arg = NULL;
+ bool cap_small = false;
if (is_slice && parg != args->end())
{
cap_arg = *parg;
cap_arg->determine_type(&int_context);
- if (!this->check_int_value(cap_arg, false))
+ if (!this->check_int_value(cap_arg, false, &cap_small))
return Expression::make_error(this->location());
Numeric_constant nclen;
@@ -7526,9 +7528,13 @@ Builtin_call_expression::lower_make(Statement_inserter* inserter)
inserter->insert(temp);
len_arg = Expression::make_temporary_reference(temp, loc);
cap_arg = Expression::make_temporary_reference(temp, loc);
+ cap_small = len_small;
}
- call = Runtime::make_call(Runtime::MAKESLICE, loc, 3, type_arg,
- len_arg, cap_arg);
+
+ Runtime::Function code = Runtime::MAKESLICE;
+ if (!len_small || !cap_small)
+ code = Runtime::MAKESLICE64;
+ call = Runtime::make_call(code, loc, 3, type_arg, len_arg, cap_arg);
}
else if (is_map)
{
@@ -7744,11 +7750,14 @@ Builtin_call_expression::flatten_append(Gogo* gogo, Named_object* function,
// Return whether an expression has an integer value. Report an error
// if not. This is used when handling calls to the predeclared make
-// function.
+// function. Set *SMALL if the value is known to fit in type "int".
bool
-Builtin_call_expression::check_int_value(Expression* e, bool is_length)
+Builtin_call_expression::check_int_value(Expression* e, bool is_length,
+ bool *small)
{
+ *small = false;
+
Numeric_constant nc;
if (e->numeric_constant_value(&nc))
{
@@ -7784,11 +7793,22 @@ Builtin_call_expression::check_int_value(Expression* e, bool is_length)
return false;
}
+ *small = true;
return true;
}
if (e->type()->integer_type() != NULL)
- return true;
+ {
+ int ebits = e->type()->integer_type()->bits();
+ int intbits = Type::lookup_integer_type("int")->integer_type()->bits();
+
+ // We can treat ebits == intbits as small even for an unsigned
+ // integer type, because we will convert the value to int and
+ // then reject it in the runtime if it is negative.
+ *small = ebits <= intbits;
+
+ return true;
+ }
go_error_at(e->location(), "non-integer %s argument to make",
is_length ? "len" : "cap");