aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.cc35
-rw-r--r--gcc/go/gofrontend/runtime.def5
3 files changed, 19 insertions, 23 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index e8cf468..eec3d07 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-be1738f1fff0e817d921ed568791f9b0585a6982
+84506e0f6bf282765856cb5aeb17124222f73042
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index d154630..23caf61 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -8893,8 +8893,8 @@ Builtin_call_expression::flatten_append(Gogo* gogo, Named_object* function,
// We will optimize this to directly zeroing the tail,
// instead of allocating a new slice then copy.
- // Retrieve the length. Cannot reference s2 as we will remove
- // the makeslice call.
+ // Retrieve the length and capacity. Cannot reference s2 as
+ // we will remove the makeslice call.
Expression* len_arg = makecall->args()->at(1);
len_arg = Expression::make_cast(int_type, len_arg, loc);
l2tmp = Statement::make_temporary(int_type, len_arg, loc);
@@ -8907,28 +8907,19 @@ Builtin_call_expression::flatten_append(Gogo* gogo, Named_object* function,
inserter->insert(c2tmp);
// Check bad len/cap here.
- // if len2 < 0 { panicmakeslicelen(); }
+ // checkmakeslice(type, len, cap)
+ // (Note that if len and cap are constants, we won't see a
+ // makeslice call here, as it will be rewritten to a stack
+ // allocated array by Mark_address_taken::expression.)
+ Expression* elem = Expression::make_type_descriptor(element_type,
+ loc);
len2 = Expression::make_temporary_reference(l2tmp, loc);
- Expression* zero = Expression::make_integer_ul(0, int_type, loc);
- Expression* cond = Expression::make_binary(OPERATOR_LT, len2,
- zero, loc);
- Expression* call = Runtime::make_call(Runtime::PANIC_MAKE_SLICE_LEN,
- loc, 0);
- cond = Expression::make_conditional(cond, call, zero->copy(), loc);
- gogo->lower_expression(function, inserter, &cond);
- gogo->flatten_expression(function, inserter, &cond);
- Statement* s = Statement::make_statement(cond, false);
- inserter->insert(s);
-
- // if cap2 < 0 { panicmakeslicecap(); }
Expression* cap2 = Expression::make_temporary_reference(c2tmp, loc);
- cond = Expression::make_binary(OPERATOR_LT, cap2,
- zero->copy(), loc);
- call = Runtime::make_call(Runtime::PANIC_MAKE_SLICE_CAP, loc, 0);
- cond = Expression::make_conditional(cond, call, zero->copy(), loc);
- gogo->lower_expression(function, inserter, &cond);
- gogo->flatten_expression(function, inserter, &cond);
- s = Statement::make_statement(cond, false);
+ Expression* check = Runtime::make_call(Runtime::CHECK_MAKE_SLICE,
+ loc, 3, elem, len2, cap2);
+ gogo->lower_expression(function, inserter, &check);
+ gogo->flatten_expression(function, inserter, &check);
+ Statement* s = Statement::make_statement(check, false);
inserter->insert(s);
// Remove the original makeslice call.
diff --git a/gcc/go/gofrontend/runtime.def b/gcc/go/gofrontend/runtime.def
index b608766..9a3c680 100644
--- a/gcc/go/gofrontend/runtime.def
+++ b/gcc/go/gofrontend/runtime.def
@@ -265,6 +265,11 @@ DEF_GO_RUNTIME(GROWSLICE, "runtime.growslice",
P5(TYPE, POINTER, INT, INT, INT), R1(SLICE))
+// Check the length and cap passed to make, without making a slice.
+// This is used for apend(s, make([]T, len)...).
+DEF_GO_RUNTIME(CHECK_MAKE_SLICE, "runtime.checkMakeSlice", P3(TYPE, INT, INT),
+ R1(UINTPTR))
+
// Register roots (global variables) for the garbage collector.
DEF_GO_RUNTIME(REGISTER_GC_ROOTS, "runtime.registerGCRoots", P1(POINTER), R0())