Commit a75e347a authored by Russ Cox's avatar Russ Cox

do not migrate x to the heap because of *&x.

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