]> Cypherpunks repositories - gostls13.git/commitdiff
bug in conv(string, bytearray)
authorKen Thompson <ken@golang.org>
Tue, 2 Sep 2008 23:21:30 +0000 (16:21 -0700)
committerKen Thompson <ken@golang.org>
Tue, 2 Sep 2008 23:21:30 +0000 (16:21 -0700)
R=r
OCL=14732
CL=14732

src/cmd/gc/go.h
src/cmd/gc/subr.c
src/cmd/gc/walk.c

index c2d46e23f5dc3583fa1ec515e0c5be71704aaba3..121a019e57da01b70719508df9172850d875a520 100644 (file)
@@ -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
index b925e5061e1a9dff4033d75058d2bd022a62db89..56958caff9b8e64a298bb42192406ef6578bcbc4 100644 (file)
@@ -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
index b9ec0c1e10896e6a79edee4fa72c079ee2eb8398..f44106695c157f4c80f998b389c26e3ce0df1777 100644 (file)
@@ -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;
+}