Commit 6592456f authored by Russ Cox's avatar Russ Cox

cmd/gc: do not generate code for var _ = ... unless necessary

Fixes #2443.

R=ken2
CC=golang-dev
https://golang.org/cl/6997048
parent a4600126
......@@ -1375,6 +1375,7 @@ void walkexprlistsafe(NodeList *l, NodeList **init);
void walkstmt(Node **np);
void walkstmtlist(NodeList *l);
Node* conv(Node*, Type*);
int candiscard(Node*);
/*
* arch-specific ggen.c/gsubr.c/gobj.c/pgen.c
......
......@@ -55,6 +55,10 @@ anyinit(NodeList *n)
case ODCLTYPE:
case OEMPTY:
break;
case OAS:
if(isblank(l->n->left) && candiscard(l->n->right))
break;
// fall through
default:
return 1;
}
......
......@@ -108,6 +108,13 @@ init1(Node *n, NodeList **out)
case OAS:
if(n->defn->left != n)
goto bad;
if(isblank(n->defn->left) && candiscard(n->defn->right)) {
n->defn->op = OEMPTY;
n->defn->left = N;
n->defn->right = N;
break;
}
/*
n->defn->dodata = 1;
init1(n->defn->right, out);
......
......@@ -183,8 +183,8 @@ walkstmt(Node **np)
dump("nottop", n);
break;
case OASOP:
case OAS:
case OASOP:
case OAS2:
case OAS2DOTTYPE:
case OAS2RECV:
......@@ -3226,3 +3226,112 @@ usefield(Node *n)
curfn->paramfld = l;
}
static int
candiscardlist(NodeList *l)
{
for(; l; l=l->next)
if(!candiscard(l->n))
return 0;
return 1;
}
int
candiscard(Node *n)
{
if(n == N)
return 1;
switch(n->op) {
default:
return 0;
case ONAME:
case ONONAME:
case OTYPE:
case OPACK:
case OLITERAL:
case OADD:
case OSUB:
case OOR:
case OXOR:
case OADDSTR:
case OADDR:
case OANDAND:
case OARRAYBYTESTR:
case OARRAYRUNESTR:
case OSTRARRAYBYTE:
case OSTRARRAYRUNE:
case OCAP:
case OCMPIFACE:
case OCMPSTR:
case OCOMPLIT:
case OMAPLIT:
case OSTRUCTLIT:
case OARRAYLIT:
case OPTRLIT:
case OCONV:
case OCONVIFACE:
case OCONVNOP:
case ODOT:
case OEQ:
case ONE:
case OLT:
case OLE:
case OGT:
case OGE:
case OKEY:
case OLEN:
case OMUL:
case OLSH:
case ORSH:
case OAND:
case OANDNOT:
case ONEW:
case ONOT:
case OCOM:
case OPLUS:
case OMINUS:
case OOROR:
case OPAREN:
case ORUNESTR:
case OREAL:
case OIMAG:
case OCOMPLEX:
// Discardable as long as the subpieces are.
break;
case ODIV:
case OMOD:
// Discardable as long as we know it's not division by zero.
if(isconst(n->right, CTINT) && mpcmpfixc(n->right->val.u.xval, 0) != 0)
break;
if(isconst(n->right, CTFLT) && mpcmpfltc(n->right->val.u.fval, 0) != 0)
break;
return 0;
case OMAKECHAN:
case OMAKEMAP:
// Discardable as long as we know it won't fail because of a bad size.
if(isconst(n->left, CTINT) && mpcmpfixc(n->left->val.u.xval, 0) == 0)
break;
return 0;
case OMAKESLICE:
// Difficult to tell what sizes are okay.
return 0;
}
if(!candiscard(n->left) ||
!candiscard(n->right) ||
!candiscard(n->ntest) ||
!candiscard(n->nincr) ||
!candiscardlist(n->ninit) ||
!candiscardlist(n->nbody) ||
!candiscardlist(n->nelse) ||
!candiscardlist(n->list) ||
!candiscardlist(n->rlist)) {
return 0;
}
return 1;
}
......@@ -16,13 +16,9 @@
== fixedbugs/
=========== fixedbugs/bug429.go
throw: all goroutines are asleep - deadlock!
fatal error: all goroutines are asleep - deadlock!
== bugs/
=========== bugs/bug395.go
bug395 is broken
=========== bugs/bug434.go
bugs/bug434.dir/two.go:10: one.t.int undefined (cannot refer to unexported field or method one.int)
BUG:bug434
......@@ -259,3 +259,13 @@ var copy_pt0a = pt0a
var copy_pt0b = pt0b
var copy_pt1 = pt1
var copy_pt1a = pt1a
var _ interface{} = 1
type T1 int
func (t *T1) M() {}
type Mer interface { M() }
var _ Mer = (*T1)(nil)
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