aboutsummaryrefslogtreecommitdiff
path: root/gcc/go/gofrontend/expressions.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2020-11-28 06:48:54 -0800
committerIan Lance Taylor <iant@golang.org>2020-11-30 12:22:14 -0800
commit9ebad4b01c22d4c03a3552fd6b0e86c9de0ce6bd (patch)
treeff2741f17fb80f494bd1ce08b2b31e8605e0c90d /gcc/go/gofrontend/expressions.cc
parente848a83f46f15280ad654f05545cc5ec4f5b8e50 (diff)
downloadgcc-9ebad4b01c22d4c03a3552fd6b0e86c9de0ce6bd.zip
gcc-9ebad4b01c22d4c03a3552fd6b0e86c9de0ce6bd.tar.gz
gcc-9ebad4b01c22d4c03a3552fd6b0e86c9de0ce6bd.tar.bz2
compiler, runtime: check len/cap for append(s, make(T, l)...)
The overflow checks done in growslice always reported an error for the capacity argument, even if it was the length argument that overflowed. This change lets the code pass the current issue4085b.go test. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/273806
Diffstat (limited to 'gcc/go/gofrontend/expressions.cc')
-rw-r--r--gcc/go/gofrontend/expressions.cc35
1 files changed, 13 insertions, 22 deletions
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.