summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2009-11-18 14:26:28 -0800
committerRuss Cox <rsc@golang.org>2009-11-18 14:26:28 -0800
commit7ff4b4ecfd81ea64494d31e201c29d954683f3d9 (patch)
treeb079ec47ceb454e0616335e2f90e8d79c3612c9f
parentc0153e764ab8d53abed51087988140a797e168f0 (diff)
downloadgolang-7ff4b4ecfd81ea64494d31e201c29d954683f3d9.tar.gz
gc: allow implicit conversion of *[10]int -> []int
when used as arg to copy. R=ken2 http://codereview.appspot.com/157071
-rw-r--r--src/cmd/gc/typecheck.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c
index 3e8823785..6dab9d761 100644
--- a/src/cmd/gc/typecheck.c
+++ b/src/cmd/gc/typecheck.c
@@ -32,6 +32,7 @@ static void checklvalue(Node*, char*);
static void checkassign(Node*);
static void checkassignlist(NodeList*);
static int islvalue(Node*);
+static void toslice(Node**);
void
typechecklist(NodeList *l, int top)
@@ -777,12 +778,16 @@ reswitch:
n->type = types[TINT];
typecheck(&n->left, Erv);
typecheck(&n->right, Erv);
+ if(n->left->type == T || n->right->type == T)
+ goto error;
+ toslice(&n->left);
+ toslice(&n->right);
if(!isslice(n->left->type) || !isslice(n->right->type)) {
- yyerror("arguments to copy must be slices");
+ yyerror("arguments to copy must be slices or array pointers");
goto error;
}
if(!eqtype(n->left->type, n->right->type)) {
- yyerror("arguments to copy must be slices of the same type");
+ yyerror("arguments to copy must have the same type element type");
goto error;
}
goto ret;
@@ -1120,6 +1125,25 @@ implicitstar(Node **nn)
*nn = n;
}
+static void
+toslice(Node **nn)
+{
+ Node *n;
+ Type *t;
+
+ n = *nn;
+ if(n->type == T)
+ return;
+ if(isptr[n->type->etype] && isfixedarray(n->type->type)) {
+ // convert to slice
+ t = typ(TARRAY);
+ t->bound = -1;
+ t->type = n->type->type->type;
+ n = typecheckconv(nil, n, t, 0, "conversion of array pointer to slice");
+ *nn = n;
+ }
+}
+
static int
onearg(Node *n)
{