Index: gcc/go/gofrontend/MERGE =================================================================== --- gcc/go/gofrontend/MERGE (revision 271021) +++ gcc/go/gofrontend/MERGE (working copy) @@ -1,4 +1,4 @@ -9c8581187b1c1a30036263728370f31cb846a274 +3dbf51c01c5d0acbf9ae47f77166fa9935881749 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. Index: gcc/go/gofrontend/expressions.cc =================================================================== --- gcc/go/gofrontend/expressions.cc (revision 271021) +++ gcc/go/gofrontend/expressions.cc (working copy) @@ -12158,6 +12158,13 @@ Map_index_expression::do_flatten(Gogo* g return Expression::make_error(loc); } + // Avoid copy for string([]byte) conversions used in map keys. + // mapaccess doesn't keep the reference, so this is safe. + Type_conversion_expression* ce = this->index_->conversion_expression(); + if (ce != NULL && ce->type()->is_string_type() + && ce->expr()->type()->is_slice_type()) + ce->set_no_copy(true); + if (!Type::are_identical(mt->key_type(), this->index_->type(), Type::COMPARE_ERRORS | Type::COMPARE_TAGS, NULL)) Index: gcc/go/gofrontend/statements.cc =================================================================== --- gcc/go/gofrontend/statements.cc (revision 270993) +++ gcc/go/gofrontend/statements.cc (working copy) @@ -1307,6 +1307,13 @@ Tuple_map_assignment_statement::do_lower if (map_type == NULL) return Statement::make_error_statement(loc); + // Avoid copy for string([]byte) conversions used in map keys. + // mapaccess doesn't keep the reference, so this is safe. + Type_conversion_expression* ce = map_index->index()->conversion_expression(); + if (ce != NULL && ce->type()->is_string_type() + && ce->expr()->type()->is_slice_type()) + ce->set_no_copy(true); + Block* b = new Block(enclosing, loc); // Move out any subexpressions to make sure that functions are Index: gcc/testsuite/go.dg/mapstring.go =================================================================== --- gcc/testsuite/go.dg/mapstring.go (nonexistent) +++ gcc/testsuite/go.dg/mapstring.go (working copy) @@ -0,0 +1,11 @@ +// { dg-do compile } +// { dg-options "-fgo-debug-optimization" } + +package p + +func F(m map[string]int, a, b []byte) int { + x := m[string(a)] // { dg-error "no copy string\\(\\\[\\\]byte\\)" } + y, ok := m[string(b)] // { dg-error "no copy string\\(\\\[\\\]byte\\)" } + _ = ok + return x + y +}