Patchwork [gccgo] Permit second copy argument to be a string

login
register
mail settings
Submitter Ian Taylor
Date Nov. 10, 2010, 5:55 a.m.
Message ID <mcr4obpyb6w.fsf@google.com>
Download mbox | patch
Permalink /patch/70610/
State New
Headers show

Comments

Ian Taylor - Nov. 10, 2010, 5:55 a.m.
The Go predeclared function copy has been changed to permit the second
argument to be a string.  This patch implements that in gccgo.  This
patch also removes the support for passing the address of an array to
copy, as that conversion is no longer implicit.  Committed to gccgo
branch.

Ian

Patch

diff -r 334da9b1ccb6 go/expressions.cc
--- a/go/expressions.cc	Thu Nov 04 21:53:49 2010 -0700
+++ b/go/expressions.cc	Tue Nov 09 21:42:15 2010 -0800
@@ -7094,26 +7094,20 @@ 
 	Type* e1;
 	if (arg1_type->is_open_array_type())
 	  e1 = arg1_type->array_type()->element_type();
-	else if (arg1_type->points_to() != NULL
-		 && arg1_type->points_to()->array_type() != NULL
-		 && !arg1_type->points_to()->is_open_array_type())
-	  e1 = arg1_type->points_to()->array_type()->element_type();
 	else
 	  {
-	    this->report_error(_("both arguments must be slices"));
+	    this->report_error(_("left argument must be a slice"));
 	    break;
 	  }
 
 	Type* e2;
 	if (arg2_type->is_open_array_type())
 	  e2 = arg2_type->array_type()->element_type();
-	else if (arg2_type->points_to() != NULL
-		 && arg2_type->points_to()->array_type() != NULL
-		 && !arg2_type->points_to()->is_open_array_type())
-	  e2 = arg2_type->points_to()->array_type()->element_type();
+	else if (arg2_type->is_string_type())
+	  e2 = Type::lookup_integer_type("uint8");
 	else
 	  {
-	    this->report_error(_("both arguments must be slices"));
+	    this->report_error(_("right argument must be a slice or a string"));
 	    break;
 	  }
 
@@ -7550,43 +7544,27 @@ 
 	  return error_mark_node;
 
 	Type* arg1_type = arg1->type();
-	Array_type* at;
-	tree arg1_val;
-	if (!arg1_type->is_open_array_type())
-	  {
-	    gcc_assert(arg1_type->points_to() != NULL
-		       && arg1_type->points_to()->array_type() != NULL
-		       && !arg1_type->points_to()->is_open_array_type());
-	    // ARG1_TREE is already a pointer to the array.
-	    arg1_val = fold_convert_loc(location, ptr_type_node, arg1_tree);
-	    at = arg1_type->points_to()->array_type();
-	  }
-	else
-	  {
-	    at = arg1_type->array_type();
-	    arg1_tree = save_expr(arg1_tree);
-	    arg1_val = at->value_pointer_tree(gogo, arg1_tree);
-	  }
+	Array_type* at = arg1_type->array_type();
+	arg1_tree = save_expr(arg1_tree);
+	tree arg1_val = at->value_pointer_tree(gogo, arg1_tree);
 	tree arg1_len = at->length_tree(gogo, arg1_tree);
 
 	Type* arg2_type = arg2->type();
 	tree arg2_val;
-	if (!arg2_type->is_open_array_type())
-	  {
-	    gcc_assert(arg2_type->points_to() != NULL
-		       && arg2_type->points_to()->array_type() != NULL
-		       && !arg2_type->points_to()->is_open_array_type());
-	    // ARG2_TREE is already a pointer to the array.
-	    arg2_val = fold_convert_loc(location, ptr_type_node, arg2_tree);
-	    at = arg2_type->points_to()->array_type();
-	  }
-	else
+	tree arg2_len;
+	if (arg2_type->is_open_array_type())
 	  {
 	    at = arg2_type->array_type();
 	    arg2_tree = save_expr(arg2_tree);
 	    arg2_val = at->value_pointer_tree(gogo, arg2_tree);
+	    arg2_len = at->length_tree(gogo, arg2_tree);
 	  }
-	tree arg2_len = at->length_tree(gogo, arg2_tree);
+	else
+	  {
+	    arg2_tree = save_expr(arg2_tree);
+	    arg2_val = String_type::bytes_tree(gogo, arg2_tree);
+	    arg2_len = String_type::length_tree(gogo, arg2_tree);
+	  }
 
 	arg1_len = save_expr(arg1_len);
 	arg2_len = save_expr(arg2_len);