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
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
* 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) {
*/
case OADDR:
ok |= Erv;
- typecheck(&n->left, Erv);
+ typecheck(&n->left, Erv | Eaddr);
if(n->left->type == T)
goto error;
switch(n->left->op) {
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;
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;
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;
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;