]> Cypherpunks repositories - gostls13.git/commitdiff
code to assign nil to an interface
authorKen Thompson <ken@golang.org>
Tue, 1 Apr 2008 02:19:37 +0000 (19:19 -0700)
committerKen Thompson <ken@golang.org>
Tue, 1 Apr 2008 02:19:37 +0000 (19:19 -0700)
without conversions

SVN=114453

src/c/gen.c
src/c/gen.h
src/c/go.h
src/c/gsubr.c
src/c/obj.c
src/c/subr.c

index 0644d17651fc0e5cd536a80831a100c18666273d..99993145b787bc0d8cfe85ff09c7f7b2c696ac89 100644 (file)
@@ -827,19 +827,19 @@ loop:
                        break;
 
                case PAS_SINGLE: // single return val used in expr
-                       if(nr == N) {
+                       if(nr == N || isnil(nr)) {
                                if(nl->addable) {
                                        gopcodet(PSTOREZ, nl->type, nl);
                                        break;
                                }
                                agen(nl);
-                               gopcodet(PSTOREZIP, nl->type, N);
+                               gopcodet(PSTOREZI, nl->type, N);
                                break;
                        }
 
                        if(nl->addable) {
                                cgen(nr);
-                               genconv(nl->type, nr->type);
+                               genconv(nl, nr);
                                gopcodet(PSTORE, nl->type, nl);
                                break;
                        }
@@ -851,7 +851,7 @@ loop:
                        }
                        if(!usesptr(nr)) {
                                cgen(nr);
-                               genconv(nl->type, nr->type);
+                               genconv(nl, nr);
                                agen(nl);
                                gopcodet(PSTOREI, nr->type, N);
                                break;
@@ -860,7 +860,7 @@ loop:
                        r = tempname(ptrto(nl->type));
                        gopcode(PSTORE, PTADDR, r);
                        cgen(nr);
-                       genconv(nl->type, nr->type);
+                       genconv(nl, nr);
                        gopcode(PLOAD, PTADDR, r);
                        gopcodet(PSTOREI, nl->type, N);
                        break;
@@ -964,7 +964,7 @@ cgen_ret(Node *n)
                        gopcodet(PSTOREI, arg->type, arg);
                } else {
                        cgen(arg);
-                       genconv(f->type, arg->type);
+                       genconv(f, arg);
                        gopcode(PLOAD, PTADDR, a->nname);
                        gopcode(PADDO, PTADDR, f->nname);
                        gopcodet(PSTOREI, f->type, N);
@@ -1010,7 +1010,7 @@ cgen_call(Node *n, int toss)
                        gopcodet(PSTOREI, at->type, ae);
                } else {
                        cgen(ae);
-                       genconv(at->type, ae->type);
+                       genconv(at, ae);
                        gopcode(PADDR, PTADDR, sn);
                        gopcode(PADDO, PTADDR, at->nname);
                        gopcodet(PSTOREI, at->type, N);
@@ -1120,9 +1120,13 @@ genprint(Node *n)
 int
 needconvert(Node *tl, Node *tr)
 {
-       if(isinter(tl))
-               if(isptrto(tr, TSTRUCT) || isinter(tr))
+       if(isinter(tl)) {
+               if(isptrto(tr, TSTRUCT))
                        return 1;
+               if(isinter(tr))
+                       return 1;
+               return 0;
+       }
        if(isptrto(tl, TSTRUCT))
                if(isinter(tr))
                        return 1;
@@ -1130,8 +1134,12 @@ needconvert(Node *tl, Node *tr)
 }
 
 void
-genconv(Node *tl, Node *tr)
+genconv(Node *l, Node *r)
 {
+       Node *tl, *tr;
+
+       tl = l->type;
+       tr = r->type;
        if(needconvert(tl, tr))
                gopcode(PCONV, PTNIL, nod(OCONV, tl, tr));
 }
index 13383141add2dd03ab974dc0d2edaf18191bd70d..9ccef592659cdab4b5d8f3c50a82133717d553f1 100644 (file)
@@ -103,7 +103,7 @@ enum
 
        PLOAD, PLOADI,
        PSTORE, PSTOREI,
-       PSTOREZ, PSTOREZIP,
+       PSTOREZ, PSTOREZI,
        PCONV, PADDR, PADDO, PINDEX, PINDEXZ,
        PSLICE,
 
index 73cc8da1c909fe63945eb4d5767401738e725f20..003bb0d2e465d6b6a7f24087ad4deded944de9fd 100644 (file)
@@ -395,6 +395,7 @@ Node*       unrev(Node*);
 void   dodump(Node*, int);
 void   dump(char*, Node*);
 Node*  aindex(Node*, Node*);
+int    isnil(Node*);
 int    isptrto(Node*, int);
 int    isinter(Node*);
 int    isbytearray(Node*);
index bf6c31b5784bf7b5019a7d34a92956f7cff3bec2..2ac8ea8cf0b700f25a31c48b14fd0ccfad019e0f 100644 (file)
@@ -236,6 +236,7 @@ pnames[] =
        [PSTORE]        = "STORE",
        [PSTOREI]       = "STOREI",
        [PSTOREZ]       = "STOREZ",
+       [PSTOREZI]      = "STOREZI",
        [PCONV]         = "CONV",
        [PADDR]         = "ADDR",
        [PADDO]         = "ADDO",
index 2c220226cd382b413ace321746e2e245622fb475..f44a0f08323f06a7ad4c08b17fdc00ed2018edd5 100644 (file)
@@ -243,6 +243,27 @@ obj1(Prog *p)
                }
                break;
 
+       case PSTOREZI:
+               switch(p->pt) {
+               default:
+                       Bprint(bout, "\t*(%Q*)%R = 0;\n", p->pt, PTADDR);
+                       break;
+
+               case PTARRAY:
+               case PTSTRUCT:
+                       Bprint(bout, "\tmemset((%Q*)%R, 0, sizeof((%Q*)%R));\n", p->pt, PTADDR, p->pt, PTADDR);
+                       break;
+
+               case PTINTER:
+                       Bprint(bout, "\t((%Q*)%R)->s = 0; ((%Q*)%R)->m = 0;\n", p->pt, PTADDR, p->pt, PTADDR);
+                       break;
+
+               case PTSTRING:
+                       Bprint(bout, "\t(%Q*)%R = &nilstring;\n", p->pt, PTADDR);
+                       break;
+               }
+               break;
+
        case PCONV:
                doconv(p);
                break;
index 052179c9edc0069806eb70128857ee265efa38a1..e03cf858503071d8a0befc951e7d4aca5c7a51c5 100644 (file)
@@ -997,6 +997,18 @@ out:
        return fmtstrcpy(fp, buf);
 }
 
+int
+isnil(Node *n)
+{
+       if(n == N)
+               return 0;
+       if(n->op != OLITERAL)
+               return 0;
+       if(n->val.ctype != CTNIL)
+               return 0;
+       return 1;
+}
+
 int
 isptrto(Node *t, int et)
 {