From 6592456feb7a9f934e82f2fde1ef2b395eaa44f8 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Sun, 30 Dec 2012 12:01:53 -0500 Subject: [PATCH] cmd/gc: do not generate code for var _ = ... unless necessary Fixes #2443. R=ken2 CC=golang-dev https://golang.org/cl/6997048 --- src/cmd/gc/go.h | 1 + src/cmd/gc/init.c | 4 ++ src/cmd/gc/sinit.c | 7 +++ src/cmd/gc/walk.c | 111 ++++++++++++++++++++++++++++++++++++++++++++- test/golden.out | 6 +-- test/sinit.go | 10 ++++ 6 files changed, 133 insertions(+), 6 deletions(-) diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 071422367c..accb19cd99 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -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 diff --git a/src/cmd/gc/init.c b/src/cmd/gc/init.c index be402cc0ce..918d37180b 100644 --- a/src/cmd/gc/init.c +++ b/src/cmd/gc/init.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; } diff --git a/src/cmd/gc/sinit.c b/src/cmd/gc/sinit.c index e8010099d2..e1a0758da1 100644 --- a/src/cmd/gc/sinit.c +++ b/src/cmd/gc/sinit.c @@ -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); diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index 98b2a4fa74..3a2152b092 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -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; +} diff --git a/test/golden.out b/test/golden.out index 3e44e04c6a..742a5d3f63 100644 --- a/test/golden.out +++ b/test/golden.out @@ -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 diff --git a/test/sinit.go b/test/sinit.go index ffb8ef7511..5e50e1100a 100644 --- a/test/sinit.go +++ b/test/sinit.go @@ -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) -- 2.48.1