diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index e62501f4dfb..3b0cff742eb 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -0e4aa31b26a20b6a6a2ca102b85ba8c8b8cdf876 +7822080a6e226b1e5872e2fcefac30f666f4cc1e 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 766864a535d..864b62df3b1 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -7442,7 +7442,7 @@ String_concat_expression::do_check_types(Gogo*) Expression* String_concat_expression::do_flatten(Gogo*, Named_object*, - Statement_inserter*) + Statement_inserter* inserter) { if (this->is_error_expression()) return this; @@ -7497,56 +7497,22 @@ String_concat_expression::do_flatten(Gogo*, Named_object*, } if (buf == NULL) buf = Expression::make_nil(loc); - Expression* call; - switch (this->exprs_->size()) - { - case 0: case 1: - go_unreachable(); - - case 2: case 3: case 4: case 5: - { - Expression* len = Expression::make_integer_ul(this->exprs_->size(), - NULL, loc); - Array_type* arg_type = Type::make_array_type(type, len); - arg_type->set_is_array_incomparable(); - Expression* arg = - Expression::make_array_composite_literal(arg_type, this->exprs_, - loc); - Runtime::Function code; - switch (this->exprs_->size()) - { - default: - go_unreachable(); - case 2: - code = Runtime::CONCATSTRING2; - break; - case 3: - code = Runtime::CONCATSTRING3; - break; - case 4: - code = Runtime::CONCATSTRING4; - break; - case 5: - code = Runtime::CONCATSTRING5; - break; - } - call = Runtime::make_call(code, loc, 2, buf, arg); - } - break; - - default: - { - Type* arg_type = Type::make_array_type(type, NULL); - Slice_construction_expression* sce = - Expression::make_slice_composite_literal(arg_type, this->exprs_, - loc); - sce->set_storage_does_not_escape(); - call = Runtime::make_call(Runtime::CONCATSTRINGS, loc, 2, buf, - sce); - } - break; - } - + go_assert(this->exprs_->size() > 1); + Expression* len = + Expression::make_integer_ul(this->exprs_->size(), NULL, loc); + Array_type* array_type = Type::make_array_type(type, len); + array_type->set_is_array_incomparable(); + Expression* array = + Expression::make_array_composite_literal(array_type, this->exprs_, + loc); + Temporary_statement* ts = + Statement::make_temporary(array_type, array, loc); + inserter->insert(ts); + Expression* ref = Expression::make_temporary_reference(ts, loc); + ref = Expression::make_unary(OPERATOR_AND, ref, loc); + Expression* call = + Runtime::make_call(Runtime::CONCATSTRINGS, loc, 3, buf, + ref, len->copy()); return Expression::make_cast(type, call, loc); } diff --git a/gcc/go/gofrontend/runtime.def b/gcc/go/gofrontend/runtime.def index 34c86e8aafc..c81ab79cc0f 100644 --- a/gcc/go/gofrontend/runtime.def +++ b/gcc/go/gofrontend/runtime.def @@ -36,16 +36,8 @@ DEF_GO_RUNTIME(DECODERUNE, "runtime.decoderune", P2(STRING, INT), R2(RUNE, INT)) // Concatenate strings. -DEF_GO_RUNTIME(CONCATSTRINGS, "runtime.concatstrings", P2(POINTER, SLICE), - R1(STRING)) -DEF_GO_RUNTIME(CONCATSTRING2, "runtime.concatstring2", - P2(POINTER, ARRAY2STRING), R1(STRING)) -DEF_GO_RUNTIME(CONCATSTRING3, "runtime.concatstring3", - P2(POINTER, ARRAY3STRING), R1(STRING)) -DEF_GO_RUNTIME(CONCATSTRING4, "runtime.concatstring4", - P2(POINTER, ARRAY4STRING), R1(STRING)) -DEF_GO_RUNTIME(CONCATSTRING5, "runtime.concatstring5", - P2(POINTER, ARRAY5STRING), R1(STRING)) +DEF_GO_RUNTIME(CONCATSTRINGS, "runtime.concatstrings", + P3(POINTER, POINTER, INT), R1(STRING)) // Compare two strings for equality. DEF_GO_RUNTIME(EQSTRING, "runtime.eqstring", P2(STRING, STRING), R1(BOOL)) diff --git a/libgo/go/runtime/string.go b/libgo/go/runtime/string.go index eac94bf6a8a..9bcfc9961c8 100644 --- a/libgo/go/runtime/string.go +++ b/libgo/go/runtime/string.go @@ -13,10 +13,6 @@ import ( // themselves, so that the compiler will export them. // //go:linkname concatstrings runtime.concatstrings -//go:linkname concatstring2 runtime.concatstring2 -//go:linkname concatstring3 runtime.concatstring3 -//go:linkname concatstring4 runtime.concatstring4 -//go:linkname concatstring5 runtime.concatstring5 //go:linkname slicebytetostring runtime.slicebytetostring //go:linkname slicebytetostringtmp runtime.slicebytetostringtmp //go:linkname stringtoslicebyte runtime.stringtoslicebyte @@ -38,7 +34,9 @@ type tmpBuf [tmpStringBufSize]byte // If buf != nil, the compiler has determined that the result does not // escape the calling function, so the string data can be stored in buf // if small enough. -func concatstrings(buf *tmpBuf, a []string) string { +func concatstrings(buf *tmpBuf, p *string, n int) string { + var a []string + *(*slice)(unsafe.Pointer(&a)) = slice{unsafe.Pointer(p), n, n} // idx := 0 l := 0 count := 0 @@ -73,22 +71,6 @@ func concatstrings(buf *tmpBuf, a []string) string { return s } -func concatstring2(buf *tmpBuf, a [2]string) string { - return concatstrings(buf, a[:]) -} - -func concatstring3(buf *tmpBuf, a [3]string) string { - return concatstrings(buf, a[:]) -} - -func concatstring4(buf *tmpBuf, a [4]string) string { - return concatstrings(buf, a[:]) -} - -func concatstring5(buf *tmpBuf, a [5]string) string { - return concatstrings(buf, a[:]) -} - // Buf is a fixed-size buffer for the result, // it is not nil if the result does not escape. func slicebytetostring(buf *tmpBuf, b []byte) (str string) {