Commit 9c5669bd authored by Ken Thompson's avatar Ken Thompson

bug in conv(string, bytearray)

R=r
OCL=14732
CL=14732
parent b5eddae5
......@@ -559,7 +559,7 @@ int isptrto(Type*, int);
int isptrarray(Type*);
int isptrdarray(Type*);
int isinter(Type*);
int isbytearray(Type*);
int bytearraysz(Type*);
int eqtype(Type*, Type*, int);
void argtype(Node*, Type*);
int eqargs(Type*, Type*);
......@@ -689,6 +689,7 @@ Node* reorder1(Node*);
Node* reorder2(Node*);
Node* reorder3(Node*);
Node* reorder4(Node*);
Node* structlit(Node*);
/*
* const.c
......
......@@ -1229,18 +1229,20 @@ isinter(Type *t)
}
int
isbytearray(Type *t)
bytearraysz(Type *t)
{
if(t == T)
return 0;
return -2;
if(isptr[t->etype]) {
t = t->type;
if(t == T)
return 0;
return -2;
}
if(t->etype != TARRAY)
return 0;
return t->bound+1;
return -2;
if(!eqtype(t->type, types[TUINT8], 0))
return -2;
return t->bound; // -1 is dyn, >=0 is fixed
}
int
......
......@@ -8,6 +8,7 @@ static Type* sw1(Node*, Type*);
static Type* sw2(Node*, Type*);
static Type* sw3(Node*, Type*);
static Node* curfn;
static Node* addtop;
void
walk(Node *fn)
......@@ -38,7 +39,7 @@ isselect(Node *n)
}
void
walktype(Node *n, int top)
walktype1(Node *n, int top)
{
Node *r, *l;
Type *t;
......@@ -54,11 +55,6 @@ walktype(Node *n, int top)
* compile-time constants are evaluated.
*/
if(top == Exxx || top == Eyyy) {
dump("", n);
fatal("walktype: bad top=%d", top);
}
loop:
if(n == N)
goto ret;
......@@ -76,6 +72,11 @@ loop:
fatal("walktype: switch 1 unknown op %N", n);
goto ret;
case OLIST:
walktype(n->left, top);
n = n->right;
goto loop;
case OPRINT:
if(top != Etop)
goto nottop;
......@@ -120,11 +121,6 @@ loop:
}
goto ret;
case OLIST:
walktype(n->left, top);
n = n->right;
goto loop;
case OFOR:
if(top != Etop)
goto nottop;
......@@ -400,6 +396,8 @@ loop:
goto ret;
convlit(l, t);
if(l->type == T)
goto ret;
// nil conversion
if(eqtype(t, l->type, 0)) {
......@@ -422,7 +420,7 @@ loop:
*n = *stringop(n, top);
goto ret;
}
if(isbytearray(l->type) != 0) {
if(bytearraysz(l->type) != -2) {
n->op = OARRAY;
*n = *stringop(n, top);
goto ret;
......@@ -433,16 +431,20 @@ loop:
if(isptrarray(t) && isptrdarray(l->type))
goto ret;
// if(t->etype == TARRAY) {
// arrayconv(t, l);
// goto ret;
// }
// interface and structure
r = isandss(n->type, l);
if(r != N) {
*n = *r;
goto ret;
}
// structure literal
if(t->etype == TSTRUCT) {
r = structlit(n);
*n = *r;
goto ret;
}
badtype(n->op, l->type, t);
goto ret;
......@@ -1591,6 +1593,7 @@ Node*
stringop(Node *n, int top)
{
Node *r, *c, *on;
Type *t;
int32 l;
switch(n->op) {
......@@ -1674,15 +1677,24 @@ stringop(Node *n, int top)
break;
case OARRAY:
// byteastring(a, l)
// byteastring(*byte, int32) string;
t = n->left->type;
l = bytearraysz(t);
// &a[0]
c = nodintconst(0);
r = nod(OINDEX, n->left, c);
r = nod(OADDR, r, N);
l = isbytearray(n->left->type);
c = nodintconst(l-1);
if(l >= 0) {
// static size
c = nodintconst(l);
} else {
// dynamic size
c = nod(OLEN, n->left, N);
}
r = list(r, c);
on = syslook("byteastring", 0);
r = nod(OCALL, on, r);
break;
......@@ -2309,6 +2321,20 @@ arrayop(Node *n, int top)
return r;
}
void
walktype(Node *n, int top)
{
Node *r;
walktype1(n, top);
while(top == Etop && addtop != N) {
r = addtop;
addtop = N;
walktype1(r, top);
n->ninit = list(r, n->ninit);
}
}
void
diagnamed(Type *t)
{
......@@ -2420,34 +2446,6 @@ bad:
return n;
}
//void
//arrayconv(Type *t, Node *n)
//{
// int c;
// Iter save;
// Node *l;
//
// l = listfirst(&save, &n);
// c = 0;
//
//loop:
// if(l == N) {
// if(t->bound == 0)
// t->bound = c;
// if(t->bound == 0 || t->bound < c)
// yyerror("error with array convert bounds");
// return;
// }
//
// c++;
// walktype(l, Erv);
// convlit(l, t->type);
// if(!ascompat(l->type, t->type))
// badtype(OARRAY, l->type, t->type);
// l = listnext(&save);
// goto loop;
//}
Node*
old2new(Node *n, Type *t)
{
......@@ -2818,3 +2816,40 @@ reorder4(Node *n)
*/
return n;
}
Node*
structlit(Node *n)
{
Iter savel, saver;
Type *l, *t;
Node *var, *r, *a;
t = n->type;
if(t->etype != TSTRUCT)
fatal("structlit: not struct");
print("\nstruct lit %lT\n", t);
var = nod(OXXX, N, N);
tempname(var, t);
l = structfirst(&savel, &n->type);
r = listfirst(&saver, &n->left);
loop:
if(l == T || r == N) {
if(l != T || r != N)
yyerror("error in shape struct literal");
return var;
}
// build list of var.field = expr
a = nod(ODOT, var, newname(l->sym));
a = nod(OAS, a, r);
addtop = list(addtop, a);
l = structnext(&savel);
r = listnext(&saver);
goto loop;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment