]> Cypherpunks repositories - gostls13.git/commitdiff
do not migrate x to the heap because of *&x.
authorRuss Cox <rsc@golang.org>
Thu, 15 Oct 2009 23:03:01 +0000 (16:03 -0700)
committerRuss Cox <rsc@golang.org>
Thu, 15 Oct 2009 23:03:01 +0000 (16:03 -0700)
R=ken
OCL=35799
CL=35799

src/cmd/gc/go.h
src/cmd/gc/typecheck.c

index 058f839cdda384571bc8cadef97a2df6590534f6..2f23d63fd96771ff20c265603d55cf95f1bb3990 100644 (file)
@@ -477,6 +477,8 @@ enum
        Efnstruct = 1<<5,       // multivalue function returns are ok
        Eiota = 1<<6,           // iota is ok
        Easgn = 1<<7,           // assigning to expression
+       Eindir = 1<<8,          // indirecting through expression
+       Eaddr = 1<<9,           // taking address of expression
 };
 
 #define        BITS    5
index 826d740cc8979a771b8a81a521c89f399b0684b6..6c90004cfb8eb5526e39dc6ef22e6fdcad3213ab 100644 (file)
@@ -51,7 +51,7 @@ typecheck(Node **np, int top)
        int et, op;
        Node *n, *l, *r;
        NodeList *args;
-       int lno, ok;
+       int lno, ok, ntop;
        Type *t;
 
        // cannot type check until all the source has been parsed
@@ -250,7 +250,10 @@ reswitch:
         * type or expr
         */
        case OIND:
-               l = typecheck(&n->left, Erv | Etype);
+               ntop = Erv | Etype;
+               if(!(top & Eaddr))
+                       ntop |= Eindir;
+               l = typecheck(&n->left, ntop);
                if((t = l->type) == T)
                        goto error;
                if(l->op == OTYPE) {
@@ -409,7 +412,7 @@ reswitch:
         */
        case OADDR:
                ok |= Erv;
-               typecheck(&n->left, Erv);
+               typecheck(&n->left, Erv | Eaddr);
                if(n->left->type == T)
                        goto error;
                switch(n->left->op) {
@@ -424,7 +427,8 @@ reswitch:
                l = n->left;
                if((t = l->type) == T)
                        goto error;
-               addrescapes(n->left);
+               if(!(top & Eindir))
+                       addrescapes(n->left);
                n->type = ptrto(t);
                goto ret;
 
@@ -642,16 +646,8 @@ reswitch:
                typecheck(&n->left, Erv | Etype | Ecall);
                defaultlit(&n->left, T);
                l = n->left;
-               if(count(n->list) == 1)
-                       typecheck(&n->list->n, Erv | Efnstruct);
-               else
-                       typechecklist(n->list, Erv);
-               if((t = l->type) == T)
-                       goto error;
-               checkwidth(t);
-
-               switch(l->op) {
-               case OTYPE:
+               if(l->op == OTYPE) {
+                       // pick off before type-checking arguments
                        ok |= Erv;
                        // turn CALL(type, arg) into CONV(arg) w/ type
                        n->left = N;
@@ -660,7 +656,17 @@ reswitch:
                        n->op = OCONV;
                        n->type = l->type;
                        goto doconv;
+               }
+
+               if(count(n->list) == 1)
+                       typecheck(&n->list->n, Erv | Efnstruct);
+               else
+                       typechecklist(n->list, Erv);
+               if((t = l->type) == T)
+                       goto error;
+               checkwidth(t);
 
+               switch(l->op) {
                case ODOTINTER:
                        n->op = OCALLINTER;
                        break;
@@ -758,7 +764,7 @@ reswitch:
        case OCONV:
        doconv:
                ok |= Erv;
-               typecheck(&n->left, Erv);
+               typecheck(&n->left, Erv | (top & Eindir));
                defaultlit(&n->left, n->type);
                if((t = n->left->type) == T || n->type == T)
                        goto error;