The Go language specification says that for append(a1, a2) a1 must be a slice. If the element type of a1 is T, then a2 must be assignable to the type []T. The gccgo frontend was incorrectly requiring that a2 be assignable to the type of a1. This patch corrects that. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline.
Ian
diff -r 7a89c4b7c106 go/expressions.cc --- a/go/expressions.cc Wed Feb 01 12:44:12 2012 -0800 +++ b/go/expressions.cc Wed Feb 01 13:27:30 2012 -0800 @@ -7657,7 +7657,10 @@ this->set_is_error(); return this; } - this->lower_varargs(gogo, function, inserter, slice_type, 2); + Type* element_type = slice_type->array_type()->element_type(); + this->lower_varargs(gogo, function, inserter, + Type::make_array_type(element_type, NULL), + 2); } break; @@ -8624,16 +8627,20 @@ break; } + // The language says that the second argument must be + // assignable to a slice of the element type of the first + // argument. We already know the first argument is a slice + // type. + Array_type* at = args->front()->type()->array_type(); + Type* arg2_type = Type::make_array_type(at->element_type(), NULL); std::string reason; - if (!Type::are_assignable(args->front()->type(), args->back()->type(), - &reason)) + if (!Type::are_assignable(arg2_type, args->back()->type(), &reason)) { if (reason.empty()) - this->report_error(_("arguments 1 and 2 have different types")); + this->report_error(_("argument 2 has invalid type")); else { - error_at(this->location(), - "arguments 1 and 2 have different types (%s)", + error_at(this->location(), "argument 2 has invalid type (%s)", reason.c_str()); this->set_is_error(); }