Commit e82003e7 authored by Russ Cox's avatar Russ Cox

cmd/gc: simplify code for c2go

- Change forward reference to struct Node* to void* in liblink.
- Use explicit (Node*) casts in cmd/gc to get at that field.
- Define struct Array in go.h instead of hiding it in array.c.
- Remove some sizeof(uint32), sizeof(uint64) uses.
- Remove some ? : expressions.
- Rewrite some problematic mid-expression assignments.

Change-Id: I308c70140238a0cfffd90e133f86f442cd0e17d4
Reviewed-on: https://go-review.googlesource.com/3276Reviewed-by: 's avatarRob Pike <r@golang.org>
parent 2a74f436
...@@ -67,7 +67,7 @@ struct Addr ...@@ -67,7 +67,7 @@ struct Addr
int8 class; // for 5l, 9l int8 class; // for 5l, 9l
uint8 etype; // for 5g, 6g, 8g uint8 etype; // for 5g, 6g, 8g
int32 offset2; // for 5l, 8l int32 offset2; // for 5l, 8l
struct Node* node; // for 5g, 6g, 8g void* node; // for 5g, 6g, 8g
int64 width; // for 5g, 6g, 8g int64 width; // for 5g, 6g, 8g
}; };
......
...@@ -128,10 +128,10 @@ markautoused(Prog* p) ...@@ -128,10 +128,10 @@ markautoused(Prog* p)
continue; continue;
if (p->from.node) if (p->from.node)
p->from.node->used = 1; ((Node*)(p->from.node))->used = 1;
if (p->to.node) if (p->to.node)
p->to.node->used = 1; ((Node*)(p->to.node))->used = 1;
} }
} }
...@@ -142,11 +142,11 @@ fixautoused(Prog* p) ...@@ -142,11 +142,11 @@ fixautoused(Prog* p)
Prog **lp; Prog **lp;
for (lp=&p; (p=*lp) != P; ) { for (lp=&p; (p=*lp) != P; ) {
if (p->as == ATYPE && p->from.node && p->from.name == D_AUTO && !p->from.node->used) { if (p->as == ATYPE && p->from.node && p->from.name == D_AUTO && !((Node*)(p->from.node))->used) {
*lp = p->link; *lp = p->link;
continue; continue;
} }
if ((p->as == AVARDEF || p->as == AVARKILL) && p->to.node && !p->to.node->used) { if ((p->as == AVARDEF || p->as == AVARKILL) && p->to.node && !((Node*)(p->to.node))->used) {
// Cannot remove VARDEF instruction, because - unlike TYPE handled above - // Cannot remove VARDEF instruction, because - unlike TYPE handled above -
// VARDEFs are interspersed with other code, and a jump might be using the // VARDEFs are interspersed with other code, and a jump might be using the
// VARDEF as a target. Replace with a no-op instead. A later pass will remove // VARDEF as a target. Replace with a no-op instead. A later pass will remove
...@@ -158,10 +158,10 @@ fixautoused(Prog* p) ...@@ -158,10 +158,10 @@ fixautoused(Prog* p)
} }
if (p->from.name == D_AUTO && p->from.node) if (p->from.name == D_AUTO && p->from.node)
p->from.offset += p->from.node->stkdelta; p->from.offset += ((Node*)(p->from.node))->stkdelta;
if (p->to.name == D_AUTO && p->to.node) if (p->to.name == D_AUTO && p->to.node)
p->to.offset += p->to.node->stkdelta; p->to.offset += ((Node*)(p->to.node))->stkdelta;
lp = &p->link; lp = &p->link;
} }
......
...@@ -274,7 +274,7 @@ regopt(Prog *firstp) ...@@ -274,7 +274,7 @@ regopt(Prog *firstp)
} }
for(r = firstr; r != R; r = (Reg*)r->f.link) { for(r = firstr; r != R; r = (Reg*)r->f.link) {
p = r->f.prog; p = r->f.prog;
if(p->as == AVARDEF && isfat(p->to.node->type) && p->to.node->opt != nil) { if(p->as == AVARDEF && isfat(((Node*)(p->to.node))->type) && ((Node*)(p->to.node))->opt != nil) {
active++; active++;
walkvardef(p->to.node, r, active); walkvardef(p->to.node, r, active);
} }
......
...@@ -124,10 +124,10 @@ markautoused(Prog* p) ...@@ -124,10 +124,10 @@ markautoused(Prog* p)
continue; continue;
if (p->from.node) if (p->from.node)
p->from.node->used = 1; ((Node*)(p->from.node))->used = 1;
if (p->to.node) if (p->to.node)
p->to.node->used = 1; ((Node*)(p->to.node))->used = 1;
} }
} }
...@@ -138,11 +138,11 @@ fixautoused(Prog *p) ...@@ -138,11 +138,11 @@ fixautoused(Prog *p)
Prog **lp; Prog **lp;
for (lp=&p; (p=*lp) != P; ) { for (lp=&p; (p=*lp) != P; ) {
if (p->as == ATYPE && p->from.node && p->from.type == D_AUTO && !p->from.node->used) { if (p->as == ATYPE && p->from.node && p->from.type == D_AUTO && !((Node*)(p->from.node))->used) {
*lp = p->link; *lp = p->link;
continue; continue;
} }
if ((p->as == AVARDEF || p->as == AVARKILL) && p->to.node && !p->to.node->used) { if ((p->as == AVARDEF || p->as == AVARKILL) && p->to.node && !((Node*)(p->to.node))->used) {
// Cannot remove VARDEF instruction, because - unlike TYPE handled above - // Cannot remove VARDEF instruction, because - unlike TYPE handled above -
// VARDEFs are interspersed with other code, and a jump might be using the // VARDEFs are interspersed with other code, and a jump might be using the
// VARDEF as a target. Replace with a no-op instead. A later pass will remove // VARDEF as a target. Replace with a no-op instead. A later pass will remove
...@@ -153,10 +153,10 @@ fixautoused(Prog *p) ...@@ -153,10 +153,10 @@ fixautoused(Prog *p)
continue; continue;
} }
if (p->from.type == D_AUTO && p->from.node) if (p->from.type == D_AUTO && p->from.node)
p->from.offset += p->from.node->stkdelta; p->from.offset += ((Node*)(p->from.node))->stkdelta;
if (p->to.type == D_AUTO && p->to.node) if (p->to.type == D_AUTO && p->to.node)
p->to.offset += p->to.node->stkdelta; p->to.offset += ((Node*)(p->to.node))->stkdelta;
lp = &p->link; lp = &p->link;
} }
......
...@@ -255,7 +255,7 @@ regopt(Prog *firstp) ...@@ -255,7 +255,7 @@ regopt(Prog *firstp)
} }
for(r = firstr; r != R; r = (Reg*)r->f.link) { for(r = firstr; r != R; r = (Reg*)r->f.link) {
p = r->f.prog; p = r->f.prog;
if(p->as == AVARDEF && isfat(p->to.node->type) && p->to.node->opt != nil) { if(p->as == AVARDEF && isfat(((Node*)(p->to.node))->type) && ((Node*)(p->to.node))->opt != nil) {
active++; active++;
walkvardef(p->to.node, r, active); walkvardef(p->to.node, r, active);
} }
......
...@@ -114,10 +114,10 @@ markautoused(Prog* p) ...@@ -114,10 +114,10 @@ markautoused(Prog* p)
continue; continue;
if (p->from.node) if (p->from.node)
p->from.node->used = 1; ((Node*)(p->from.node))->used = 1;
if (p->to.node) if (p->to.node)
p->to.node->used = 1; ((Node*)(p->to.node))->used = 1;
} }
} }
...@@ -128,11 +128,11 @@ fixautoused(Prog* p) ...@@ -128,11 +128,11 @@ fixautoused(Prog* p)
Prog **lp; Prog **lp;
for (lp=&p; (p=*lp) != P; ) { for (lp=&p; (p=*lp) != P; ) {
if (p->as == ATYPE && p->from.node && p->from.type == D_AUTO && !p->from.node->used) { if (p->as == ATYPE && p->from.node && p->from.type == D_AUTO && !((Node*)(p->from.node))->used) {
*lp = p->link; *lp = p->link;
continue; continue;
} }
if ((p->as == AVARDEF || p->as == AVARKILL) && p->to.node && !p->to.node->used) { if ((p->as == AVARDEF || p->as == AVARKILL) && p->to.node && !((Node*)(p->to.node))->used) {
// Cannot remove VARDEF instruction, because - unlike TYPE handled above - // Cannot remove VARDEF instruction, because - unlike TYPE handled above -
// VARDEFs are interspersed with other code, and a jump might be using the // VARDEFs are interspersed with other code, and a jump might be using the
// VARDEF as a target. Replace with a no-op instead. A later pass will remove // VARDEF as a target. Replace with a no-op instead. A later pass will remove
...@@ -144,10 +144,10 @@ fixautoused(Prog* p) ...@@ -144,10 +144,10 @@ fixautoused(Prog* p)
} }
if (p->from.type == D_AUTO && p->from.node) if (p->from.type == D_AUTO && p->from.node)
p->from.offset += p->from.node->stkdelta; p->from.offset += ((Node*)(p->from.node))->stkdelta;
if (p->to.type == D_AUTO && p->to.node) if (p->to.type == D_AUTO && p->to.node)
p->to.offset += p->to.node->stkdelta; p->to.offset += ((Node*)(p->to.node))->stkdelta;
lp = &p->link; lp = &p->link;
} }
......
...@@ -227,7 +227,7 @@ regopt(Prog *firstp) ...@@ -227,7 +227,7 @@ regopt(Prog *firstp)
} }
for(r = firstr; r != R; r = (Reg*)r->f.link) { for(r = firstr; r != R; r = (Reg*)r->f.link) {
p = r->f.prog; p = r->f.prog;
if(p->as == AVARDEF && isfat(p->to.node->type) && p->to.node->opt != nil) { if(p->as == AVARDEF && isfat(((Node*)(p->to.node))->type) && ((Node*)(p->to.node))->opt != nil) {
active++; active++;
walkvardef(p->to.node, r, active); walkvardef(p->to.node, r, active);
} }
......
...@@ -124,10 +124,10 @@ markautoused(Prog *p) ...@@ -124,10 +124,10 @@ markautoused(Prog *p)
continue; continue;
if (p->from.node) if (p->from.node)
p->from.node->used = 1; ((Node*)(p->from.node))->used = 1;
if (p->to.node) if (p->to.node)
p->to.node->used = 1; ((Node*)(p->to.node))->used = 1;
} }
} }
...@@ -138,11 +138,11 @@ fixautoused(Prog *p) ...@@ -138,11 +138,11 @@ fixautoused(Prog *p)
Prog **lp; Prog **lp;
for (lp=&p; (p=*lp) != P; ) { for (lp=&p; (p=*lp) != P; ) {
if (p->as == ATYPE && p->from.node && p->from.name == D_AUTO && !p->from.node->used) { if (p->as == ATYPE && p->from.node && p->from.name == D_AUTO && !((Node*)(p->from.node))->used) {
*lp = p->link; *lp = p->link;
continue; continue;
} }
if ((p->as == AVARDEF || p->as == AVARKILL) && p->to.node && !p->to.node->used) { if ((p->as == AVARDEF || p->as == AVARKILL) && p->to.node && !((Node*)(p->to.node))->used) {
// Cannot remove VARDEF instruction, because - unlike TYPE handled above - // Cannot remove VARDEF instruction, because - unlike TYPE handled above -
// VARDEFs are interspersed with other code, and a jump might be using the // VARDEFs are interspersed with other code, and a jump might be using the
// VARDEF as a target. Replace with a no-op instead. A later pass will remove // VARDEF as a target. Replace with a no-op instead. A later pass will remove
...@@ -153,10 +153,10 @@ fixautoused(Prog *p) ...@@ -153,10 +153,10 @@ fixautoused(Prog *p)
continue; continue;
} }
if (p->from.name == D_AUTO && p->from.node) if (p->from.name == D_AUTO && p->from.node)
p->from.offset += p->from.node->stkdelta; p->from.offset += ((Node*)(p->from.node))->stkdelta;
if (p->to.name == D_AUTO && p->to.node) if (p->to.name == D_AUTO && p->to.node)
p->to.offset += p->to.node->stkdelta; p->to.offset += ((Node*)(p->to.node))->stkdelta;
lp = &p->link; lp = &p->link;
} }
......
...@@ -296,7 +296,7 @@ regopt(Prog *firstp) ...@@ -296,7 +296,7 @@ regopt(Prog *firstp)
} }
for(r = firstr; r != R; r = (Reg*)r->f.link) { for(r = firstr; r != R; r = (Reg*)r->f.link) {
p = r->f.prog; p = r->f.prog;
if(p->as == AVARDEF && isfat(p->to.node->type) && p->to.node->opt != nil) { if(p->as == AVARDEF && isfat(((Node*)(p->to.node))->type) && ((Node*)(p->to.node))->opt != nil) {
active++; active++;
walkvardef(p->to.node, r, active); walkvardef(p->to.node, r, active);
} }
......
...@@ -10,14 +10,6 @@ enum { ...@@ -10,14 +10,6 @@ enum {
DEFAULTCAPACITY = 16, DEFAULTCAPACITY = 16,
}; };
struct Array
{
int32 length; // number of elements
int32 size; // element size
int32 capacity; // size of data in elements
char *data; // element storage
};
Array* Array*
arraynew(int32 capacity, int32 size) arraynew(int32 capacity, int32 size)
{ {
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#include "go.h" #include "go.h"
enum { enum {
WORDSIZE = sizeof(uint32), WORDSIZE = 4,
WORDBITS = 32, WORDBITS = 32,
WORDMASK = WORDBITS - 1, WORDMASK = WORDBITS - 1,
WORDSHIFT = 5, WORDSHIFT = 5,
......
...@@ -14,6 +14,14 @@ static void minus(Node *nl, Node *res); ...@@ -14,6 +14,14 @@ static void minus(Node *nl, Node *res);
#define CASE(a,b) (((a)<<16)|((b)<<0)) #define CASE(a,b) (((a)<<16)|((b)<<0))
/*c2go
static int
CASE(int a, int b)
{
return a<<16 | b;
}
*/
static int static int
overlap(Node *f, Node *t) overlap(Node *f, Node *t)
{ {
...@@ -308,13 +316,13 @@ complexbool(int op, Node *nl, Node *nr, int true, int likely, Prog *to) ...@@ -308,13 +316,13 @@ complexbool(int op, Node *nl, Node *nr, int true, int likely, Prog *to)
na.right = &nc; na.right = &nc;
na.type = types[TBOOL]; na.type = types[TBOOL];
memset(&nb, 0, sizeof(na)); memset(&nb, 0, sizeof(nb));
nb.op = OEQ; nb.op = OEQ;
nb.left = &n1; nb.left = &n1;
nb.right = &n3; nb.right = &n3;
nb.type = types[TBOOL]; nb.type = types[TBOOL];
memset(&nc, 0, sizeof(na)); memset(&nc, 0, sizeof(nc));
nc.op = OEQ; nc.op = OEQ;
nc.left = &n2; nc.left = &n2;
nc.right = &n4; nc.right = &n4;
...@@ -442,13 +450,13 @@ complexmul(Node *nl, Node *nr, Node *res) ...@@ -442,13 +450,13 @@ complexmul(Node *nl, Node *nr, Node *res)
tempname(&tmp, n5.type); tempname(&tmp, n5.type);
// real part -> tmp // real part -> tmp
memset(&rm1, 0, sizeof(ra)); memset(&rm1, 0, sizeof(rm1));
rm1.op = OMUL; rm1.op = OMUL;
rm1.left = &n1; rm1.left = &n1;
rm1.right = &n3; rm1.right = &n3;
rm1.type = n1.type; rm1.type = n1.type;
memset(&rm2, 0, sizeof(ra)); memset(&rm2, 0, sizeof(rm2));
rm2.op = OMUL; rm2.op = OMUL;
rm2.left = &n2; rm2.left = &n2;
rm2.right = &n4; rm2.right = &n4;
...@@ -462,13 +470,13 @@ complexmul(Node *nl, Node *nr, Node *res) ...@@ -462,13 +470,13 @@ complexmul(Node *nl, Node *nr, Node *res)
cgen(&ra, &tmp); cgen(&ra, &tmp);
// imag part // imag part
memset(&rm1, 0, sizeof(ra)); memset(&rm1, 0, sizeof(rm1));
rm1.op = OMUL; rm1.op = OMUL;
rm1.left = &n1; rm1.left = &n1;
rm1.right = &n4; rm1.right = &n4;
rm1.type = n1.type; rm1.type = n1.type;
memset(&rm2, 0, sizeof(ra)); memset(&rm2, 0, sizeof(rm2));
rm2.op = OMUL; rm2.op = OMUL;
rm2.left = &n2; rm2.left = &n2;
rm2.right = &n3; rm2.right = &n3;
......
...@@ -256,7 +256,7 @@ dumpexportvar(Sym *s) ...@@ -256,7 +256,7 @@ dumpexportvar(Sym *s)
} }
static int static int
methcmp(const void *va, const void *vb) methodbyname(const void *va, const void *vb)
{ {
Type *a, *b; Type *a, *b;
...@@ -297,7 +297,7 @@ dumpexporttype(Type *t) ...@@ -297,7 +297,7 @@ dumpexporttype(Type *t)
i = 0; i = 0;
for(f=t->method; f!=T; f=f->down) for(f=t->method; f!=T; f=f->down)
m[i++] = f; m[i++] = f;
qsort(m, n, sizeof m[0], methcmp); qsort(m, n, sizeof m[0], methodbyname);
Bprint(bout, "\ttype %#S %#lT\n", t->sym, t); Bprint(bout, "\ttype %#S %#lT\n", t->sym, t);
for(i=0; i<n; i++) { for(i=0; i<n; i++) {
......
...@@ -128,10 +128,6 @@ struct Val ...@@ -128,10 +128,6 @@ struct Val
Strlit* sval; // string CTSTR Strlit* sval; // string CTSTR
} u; } u;
}; };
// prevent incompatible type signatures between libgc and 8g on Plan 9
#pragma incomplete struct Array
typedef struct Array Array; typedef struct Array Array;
typedef struct Bvec Bvec; typedef struct Bvec Bvec;
typedef struct Pkg Pkg; typedef struct Pkg Pkg;
...@@ -141,6 +137,14 @@ typedef struct NodeList NodeList; ...@@ -141,6 +137,14 @@ typedef struct NodeList NodeList;
typedef struct Type Type; typedef struct Type Type;
typedef struct Label Label; typedef struct Label Label;
struct Array
{
int32 length; // number of elements
int32 size; // element size
int32 capacity; // size of data in elements
char *data; // element storage
};
struct Type struct Type
{ {
uchar etype; uchar etype;
...@@ -708,8 +712,10 @@ enum ...@@ -708,8 +712,10 @@ enum
Ecomplit = 1<<11, // type in composite literal Ecomplit = 1<<11, // type in composite literal
}; };
#define BITS 3 enum {
#define NVAR (BITS*sizeof(uint64)*8) BITS = 3,
NVAR = (BITS*64)
};
typedef struct Bits Bits; typedef struct Bits Bits;
struct Bits struct Bits
......
...@@ -735,23 +735,23 @@ progeffects(Prog *prog, Array *vars, Bvec *uevar, Bvec *varkill, Bvec *avarinit) ...@@ -735,23 +735,23 @@ progeffects(Prog *prog, Array *vars, Bvec *uevar, Bvec *varkill, Bvec *avarinit)
} }
if(info.flags & (LeftRead | LeftWrite | LeftAddr)) { if(info.flags & (LeftRead | LeftWrite | LeftAddr)) {
from = &prog->from; from = &prog->from;
if (from->node != nil && from->sym != nil && from->node->curfn == curfn) { if (from->node != nil && from->sym != nil && ((Node*)(from->node))->curfn == curfn) {
switch(from->node->class & ~PHEAP) { switch(((Node*)(from->node))->class & ~PHEAP) {
case PAUTO: case PAUTO:
case PPARAM: case PPARAM:
case PPARAMOUT: case PPARAMOUT:
pos = (int)(uintptr)from->node->opt - 1; // index in vars pos = (int)(uintptr)((Node*)(from->node))->opt - 1; // index in vars
if(pos == -1) if(pos == -1)
goto Next; goto Next;
if(pos >= arraylength(vars) || *(Node**)arrayget(vars, pos) != from->node) if(pos >= arraylength(vars) || *(Node**)arrayget(vars, pos) != from->node)
fatal("bad bookkeeping in liveness %N %d", from->node, pos); fatal("bad bookkeeping in liveness %N %d", from->node, pos);
if(from->node->addrtaken) { if(((Node*)(from->node))->addrtaken) {
bvset(avarinit, pos); bvset(avarinit, pos);
} else { } else {
if(info.flags & (LeftRead | LeftAddr)) if(info.flags & (LeftRead | LeftAddr))
bvset(uevar, pos); bvset(uevar, pos);
if(info.flags & LeftWrite) if(info.flags & LeftWrite)
if(from->node != nil && !isfat(from->node->type)) if(from->node != nil && !isfat(((Node*)(from->node))->type))
bvset(varkill, pos); bvset(varkill, pos);
} }
} }
...@@ -760,17 +760,17 @@ progeffects(Prog *prog, Array *vars, Bvec *uevar, Bvec *varkill, Bvec *avarinit) ...@@ -760,17 +760,17 @@ progeffects(Prog *prog, Array *vars, Bvec *uevar, Bvec *varkill, Bvec *avarinit)
Next: Next:
if(info.flags & (RightRead | RightWrite | RightAddr)) { if(info.flags & (RightRead | RightWrite | RightAddr)) {
to = &prog->to; to = &prog->to;
if (to->node != nil && to->sym != nil && to->node->curfn == curfn) { if (to->node != nil && to->sym != nil && ((Node*)(to->node))->curfn == curfn) {
switch(to->node->class & ~PHEAP) { switch(((Node*)(to->node))->class & ~PHEAP) {
case PAUTO: case PAUTO:
case PPARAM: case PPARAM:
case PPARAMOUT: case PPARAMOUT:
pos = (int)(uintptr)to->node->opt - 1; // index in vars pos = (int)(uintptr)((Node*)(to->node))->opt - 1; // index in vars
if(pos == -1) if(pos == -1)
goto Next1; goto Next1;
if(pos >= arraylength(vars) || *(Node**)arrayget(vars, pos) != to->node) if(pos >= arraylength(vars) || *(Node**)arrayget(vars, pos) != to->node)
fatal("bad bookkeeping in liveness %N %d", to->node, pos); fatal("bad bookkeeping in liveness %N %d", to->node, pos);
if(to->node->addrtaken) { if(((Node*)(to->node))->addrtaken) {
if(prog->as != AVARKILL) if(prog->as != AVARKILL)
bvset(avarinit, pos); bvset(avarinit, pos);
if(prog->as == AVARDEF || prog->as == AVARKILL) if(prog->as == AVARDEF || prog->as == AVARKILL)
...@@ -787,7 +787,7 @@ Next: ...@@ -787,7 +787,7 @@ Next:
if((info.flags & RightRead) || (info.flags & (RightAddr|RightWrite)) == RightAddr) if((info.flags & RightRead) || (info.flags & (RightAddr|RightWrite)) == RightAddr)
bvset(uevar, pos); bvset(uevar, pos);
if(info.flags & RightWrite) if(info.flags & RightWrite)
if(to->node != nil && (!isfat(to->node->type) || prog->as == AVARDEF)) if(to->node != nil && (!isfat(((Node*)(to->node))->type) || prog->as == AVARDEF))
bvset(varkill, pos); bvset(varkill, pos);
} }
} }
...@@ -898,8 +898,12 @@ printnode(Node *node) ...@@ -898,8 +898,12 @@ printnode(Node *node)
char *p; char *p;
char *a; char *a;
p = haspointers(node->type) ? "^" : ""; p = "";
a = node->addrtaken ? "@" : ""; if(haspointers(node->type))
p = "^";
a = "";
if(node->addrtaken)
a = "@";
print(" %N%s%s", node, p, a); print(" %N%s%s", node, p, a);
} }
...@@ -1604,11 +1608,11 @@ livenessepilogue(Liveness *lv) ...@@ -1604,11 +1608,11 @@ livenessepilogue(Liveness *lv)
fmtstrinit(&fmt); fmtstrinit(&fmt);
fmtprint(&fmt, "%L: live at ", p->lineno); fmtprint(&fmt, "%L: live at ", p->lineno);
if(p->as == ACALL && p->to.node) if(p->as == ACALL && p->to.node)
fmtprint(&fmt, "call to %s:", p->to.node->sym->name); fmtprint(&fmt, "call to %s:", ((Node*)(p->to.node))->sym->name);
else if(p->as == ACALL) else if(p->as == ACALL)
fmtprint(&fmt, "indirect call:"); fmtprint(&fmt, "indirect call:");
else else
fmtprint(&fmt, "entry to %s:", p->from.node->sym->name); fmtprint(&fmt, "entry to %s:", ((Node*)(p->from.node))->sym->name);
numlive = 0; numlive = 0;
for(j = 0; j < arraylength(lv->vars); j++) { for(j = 0; j < arraylength(lv->vars); j++) {
n = *(Node**)arrayget(lv->vars, j); n = *(Node**)arrayget(lv->vars, j);
......
...@@ -58,7 +58,7 @@ noreturn(Prog *p) ...@@ -58,7 +58,7 @@ noreturn(Prog *p)
if(p->to.node == nil) if(p->to.node == nil)
return 0; return 0;
s = p->to.node->sym; s = ((Node*)(p->to.node))->sym;
if(s == S) if(s == S)
return 0; return 0;
for(i=0; symlist[i]!=S; i++) for(i=0; symlist[i]!=S; i++)
...@@ -586,10 +586,14 @@ mergetemp(Prog *firstp) ...@@ -586,10 +586,14 @@ mergetemp(Prog *firstp)
p = r->f.prog; p = r->f.prog;
proginfo(&info, p); proginfo(&info, p);
if(p->from.node != N && p->from.node->opt && p->to.node != N && p->to.node->opt) if(p->from.node != N && ((Node*)(p->from.node))->opt && p->to.node != N && ((Node*)(p->to.node))->opt)
fatal("double node %P", p); fatal("double node %P", p);
if((n = p->from.node) != N && (v = n->opt) != nil || v = nil;
(n = p->to.node) != N && (v = n->opt) != nil) { if((n = p->from.node) != N)
v = n->opt;
if(v == nil && (n = p->to.node) != N)
v = n->opt;
if(v != nil) {
if(v->def == nil) if(v->def == nil)
v->def = r; v->def = r;
r->uselink = v->use; r->uselink = v->use;
......
...@@ -708,7 +708,7 @@ static int ...@@ -708,7 +708,7 @@ static int
methcmp(const void *va, const void *vb) methcmp(const void *va, const void *vb)
{ {
Type *a, *b; Type *a, *b;
int i; int k;
a = *(Type**)va; a = *(Type**)va;
b = *(Type**)vb; b = *(Type**)vb;
...@@ -718,13 +718,13 @@ methcmp(const void *va, const void *vb) ...@@ -718,13 +718,13 @@ methcmp(const void *va, const void *vb)
return -1; return -1;
if(b->sym == S) if(b->sym == S)
return 1; return 1;
i = strcmp(a->sym->name, b->sym->name); k = strcmp(a->sym->name, b->sym->name);
if(i != 0) if(k != 0)
return i; return k;
if(!exportname(a->sym->name)) { if(!exportname(a->sym->name)) {
i = strcmp(a->sym->pkg->path->s, b->sym->pkg->path->s); k = strcmp(a->sym->pkg->path->s, b->sym->pkg->path->s);
if(i != 0) if(k != 0)
return i; return k;
} }
return 0; return 0;
} }
......
...@@ -586,7 +586,9 @@ reswitch: ...@@ -586,7 +586,9 @@ reswitch:
l->typecheck = 1; l->typecheck = 1;
n->left = l; n->left = l;
t = l->type; t = l->type;
} else if(l->type->etype != TBLANK && (aop = assignop(r->type, l->type, nil)) != 0) { goto converted;
}
if(l->type->etype != TBLANK && (aop = assignop(r->type, l->type, nil)) != 0) {
if(isinter(l->type) && !isinter(r->type) && algtype1(r->type, nil) == ANOEQ) { if(isinter(l->type) && !isinter(r->type) && algtype1(r->type, nil) == ANOEQ) {
yyerror("invalid operation: %N (operator %O not defined on %s)", n, op, typekind(r->type)); yyerror("invalid operation: %N (operator %O not defined on %s)", n, op, typekind(r->type));
goto error; goto error;
...@@ -597,6 +599,7 @@ reswitch: ...@@ -597,6 +599,7 @@ reswitch:
n->right = r; n->right = r;
t = r->type; t = r->type;
} }
converted:
et = t->etype; et = t->etype;
} }
if(t->etype != TIDEAL && !eqtype(l->type, r->type)) { if(t->etype != TIDEAL && !eqtype(l->type, r->type)) {
......
...@@ -27,7 +27,9 @@ unsafenmagic(Node *nn) ...@@ -27,7 +27,9 @@ unsafenmagic(Node *nn)
fn = nn->left; fn = nn->left;
args = nn->list; args = nn->list;
if(safemode || fn == N || fn->op != ONAME || (s = fn->sym) == S) if(safemode || fn == N || fn->op != ONAME)
goto no;
if((s = fn->sym) == S)
goto no; goto no;
if(s->pkg != unsafepkg) if(s->pkg != unsafepkg)
goto no; goto no;
......
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