diff --git a/src/cmd/6g/cgen.c b/src/cmd/6g/cgen.c index 76776d70295cecd9f216250eea93cbe2b9388a45..9bca759961ee83e8b6ada1c37b0cb636d76658fe 100644 --- a/src/cmd/6g/cgen.c +++ b/src/cmd/6g/cgen.c @@ -1109,6 +1109,22 @@ sgen(Node *n, Node *ns, int32 w) restx(&cx, &oldcx); } +static int +cadable(Node *n) +{ + if(!n->addable) { + // dont know how it happens, + // but it does + return 0; + } + + switch(n->op) { + case ONAME: + return 1; + } + return 0; +} + /* * copy a structure component by component * return 1 if can do, 0 if cant. @@ -1118,20 +1134,36 @@ int componentgen(Node *nr, Node *nl) { Node nodl, nodr; - int free; + int freel, freer; - free = 0; - if(!nl->addable || nl->op != ONAME) + freel = 0; + freer = 0; + + switch(nl->type->etype) { + default: goto no; + case TARRAY: + if(!isslice(nl->type)) + goto no; + case TSTRING: + case TINTER: + break; + } + nodl = *nl; - if(nr != N) { - if(!nr->addable || nr->op != ONAME) + if(!cadable(nl)) { + if(nr == N || !cadable(nr)) goto no; + igen(nl, &nodl, N); + freel = 1; + } + + if(nr != N) { nodr = *nr; - if(nr->op != ONAME && nr->op != OINDREG) { + if(!cadable(nr)) { igen(nr, &nodr, N); - free = 1; + freer = 1; } } @@ -1173,7 +1205,6 @@ componentgen(Node *nr, Node *nl) goto yes; case TSTRING: - nodl.xoffset += Array_array; nodl.type = ptrto(types[TUINT8]); @@ -1197,7 +1228,6 @@ componentgen(Node *nr, Node *nl) goto yes; case TINTER: - nodl.xoffset += Array_array; nodl.type = ptrto(types[TUINT8]); @@ -1225,12 +1255,16 @@ componentgen(Node *nr, Node *nl) } no: - if(free) + if(freer) regfree(&nodr); + if(freel) + regfree(&nodl); return 0; yes: - if(free) + if(freer) regfree(&nodr); + if(freel) + regfree(&nodl); return 1; }