make every func literal expression allocate,
so that == on func means that the
functions originated in the same
execution of a func literal or definition.

before, there was an inconsistency:

	func() {x++} != func() {x++}

but

	func() {} == func() {}

this CL makes the second case != too,
just like

	make(map[int]int) != make(map[int]int)

R=r
DELTA=202  (71 added, 62 deleted, 69 changed)
OCL=32393
CL=32398
diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c
index 31393cf..da09ced 100644
--- a/src/cmd/gc/dcl.c
+++ b/src/cmd/gc/dcl.c
@@ -553,77 +553,73 @@
 	// as we referred to variables from the outer function,
 	// we accumulated a list of PHEAP names in func->cvars.
 	narg = 0;
-	if(func->cvars == nil)
-		ft = type;
-	else {
-		// add PHEAP versions as function arguments.
-		in = nil;
-		for(l=func->cvars; l; l=l->next) {
-			a = l->n;
-			d = nod(ODCLFIELD, a, N);
-			d->type = ptrto(a->type);
-			in = list(in, d);
-
-			// while we're here, set up a->heapaddr for back end
-			n = nod(ONAME, N, N);
-			snprint(namebuf, sizeof namebuf, "&%s", a->sym->name);
-			n->sym = lookup(namebuf);
-			n->type = ptrto(a->type);
-			n->class = PPARAM;
-			n->xoffset = narg*types[tptr]->width;
-			n->addable = 1;
-			n->ullman = 1;
-			narg++;
-			a->heapaddr = n;
-
-			a->xoffset = 0;
-
-			// unlink from actual ONAME in symbol table
-			a->closure->closure = a->outer;
-		}
-
-		// add a dummy arg for the closure's caller pc
+	// add PHEAP versions as function arguments.
+	in = nil;
+	for(l=func->cvars; l; l=l->next) {
+		a = l->n;
 		d = nod(ODCLFIELD, a, N);
-		d->type = types[TUINTPTR];
+		d->type = ptrto(a->type);
 		in = list(in, d);
 
-		// slide param offset to make room for ptrs above.
-		// narg+1 to skip over caller pc.
-		shift = (narg+1)*types[tptr]->width;
+		// while we're here, set up a->heapaddr for back end
+		n = nod(ONAME, N, N);
+		snprint(namebuf, sizeof namebuf, "&%s", a->sym->name);
+		n->sym = lookup(namebuf);
+		n->type = ptrto(a->type);
+		n->class = PPARAM;
+		n->xoffset = narg*types[tptr]->width;
+		n->addable = 1;
+		n->ullman = 1;
+		narg++;
+		a->heapaddr = n;
 
-		// now the original arguments.
-		for(t=structfirst(&save, getinarg(type)); t; t=structnext(&save)) {
-			d = nod(ODCLFIELD, t->nname, N);
-			d->type = t->type;
-			in = list(in, d);
+		a->xoffset = 0;
 
-			a = t->nname;
-			if(a != N) {
-				if(a->stackparam != N)
-					a = a->stackparam;
-				a->xoffset += shift;
-			}
-		}
-
-		// out arguments
-		out = nil;
-		for(t=structfirst(&save, getoutarg(type)); t; t=structnext(&save)) {
-			d = nod(ODCLFIELD, t->nname, N);
-			d->type = t->type;
-			out = list(out, d);
-
-			a = t->nname;
-			if(a != N) {
-				if(a->stackparam != N)
-					a = a->stackparam;
-				a->xoffset += shift;
-			}
-		}
-
-		ft = functype(N, in, out);
-		ft->outnamed = type->outnamed;
+		// unlink from actual ONAME in symbol table
+		a->closure->closure = a->outer;
 	}
 
+	// add a dummy arg for the closure's caller pc
+	d = nod(ODCLFIELD, N, N);
+	d->type = types[TUINTPTR];
+	in = list(in, d);
+
+	// slide param offset to make room for ptrs above.
+	// narg+1 to skip over caller pc.
+	shift = (narg+1)*types[tptr]->width;
+
+	// now the original arguments.
+	for(t=structfirst(&save, getinarg(type)); t; t=structnext(&save)) {
+		d = nod(ODCLFIELD, t->nname, N);
+		d->type = t->type;
+		in = list(in, d);
+
+		a = t->nname;
+		if(a != N) {
+			if(a->stackparam != N)
+				a = a->stackparam;
+			a->xoffset += shift;
+		}
+	}
+
+	// out arguments
+	out = nil;
+	for(t=structfirst(&save, getoutarg(type)); t; t=structnext(&save)) {
+		d = nod(ODCLFIELD, t->nname, N);
+		d->type = t->type;
+		out = list(out, d);
+
+		a = t->nname;
+		if(a != N) {
+			if(a->stackparam != N)
+				a = a->stackparam;
+			a->xoffset += shift;
+		}
+	}
+
+	ft = functype(N, in, out);
+	ft->outnamed = type->outnamed;
+
 	// declare function.
 	vargen++;
 	snprint(namebuf, sizeof(namebuf), "_f%.3ldĀ·%s", vargen, filename);
@@ -642,10 +638,6 @@
 	funcdepth--;
 	autodcl = func->dcl;
 
-	// if there's no closure, we can use f directly
-	if(func->cvars == nil)
-		return f;
-
 	// build up type for this instance of the closure func.
 	in = nil;
 	d = nod(ODCLFIELD, N, N);	// siz
@@ -1655,7 +1647,7 @@
 	Type *tv;
 	NodeList *r;
 	Type *t;
-	
+
 	t = T;
 	if(nt) {
 		walkexpr(nt, Etype, &nt->ninit);
diff --git a/src/pkg/runtime/386/closure.c b/src/pkg/runtime/386/closure.c
index 6ccbe3b..1a211bd 100644
--- a/src/pkg/runtime/386/closure.c
+++ b/src/pkg/runtime/386/closure.c
@@ -43,41 +43,44 @@
 	p = mal(n);
 	*ret = p;
 	q = p + n - siz;
-	mcpy(q, (byte*)&arg0, siz);
 
-	// SUBL $siz, SP
-	*p++ = 0x81;
-	*p++ = 0xec;
-	*(uint32*)p = siz;
-	p += 4;
+	if(siz > 0) {
+		mcpy(q, (byte*)&arg0, siz);
 
-	// MOVL $q, SI
-	*p++ = 0xbe;
-	*(byte**)p = q;
-	p += 4;
-
-	// MOVL SP, DI
-	*p++ = 0x89;
-	*p++ = 0xe7;
-
-	// CLD
-	*p++ = 0xfc;
-
-	if(siz <= 4*4) {
-		for(i=0; i<siz; i+=4) {
-			// MOVSL
-			*p++ = 0xa5;
-		}
-	} else {
-		// MOVL $(siz/4), CX  [32-bit immediate siz/4]
-		*p++ = 0xc7;
-		*p++ = 0xc1;
-		*(uint32*)p = siz/4;
+		// SUBL $siz, SP
+		*p++ = 0x81;
+		*p++ = 0xec;
+		*(uint32*)p = siz;
 		p += 4;
 
-		// REP; MOVSL
-		*p++ = 0xf3;
-		*p++ = 0xa5;
+		// MOVL $q, SI
+		*p++ = 0xbe;
+		*(byte**)p = q;
+		p += 4;
+
+		// MOVL SP, DI
+		*p++ = 0x89;
+		*p++ = 0xe7;
+
+		// CLD
+		*p++ = 0xfc;
+
+		if(siz <= 4*4) {
+			for(i=0; i<siz; i+=4) {
+				// MOVSL
+				*p++ = 0xa5;
+			}
+		} else {
+			// MOVL $(siz/4), CX  [32-bit immediate siz/4]
+			*p++ = 0xc7;
+			*p++ = 0xc1;
+			*(uint32*)p = siz/4;
+			p += 4;
+
+			// REP; MOVSL
+			*p++ = 0xf3;
+			*p++ = 0xa5;
+		}
 	}
 
 	// call fn
diff --git a/src/pkg/runtime/amd64/closure.c b/src/pkg/runtime/amd64/closure.c
index 5717d3c..21ac7c3 100644
--- a/src/pkg/runtime/amd64/closure.c
+++ b/src/pkg/runtime/amd64/closure.c
@@ -43,47 +43,49 @@
 	p = mal(n);
 	*ret = p;
 	q = p + n - siz;
-	mcpy(q, (byte*)&arg0, siz);
 
-	// SUBQ $siz, SP
-	*p++ = 0x48;
-	*p++ = 0x81;
-	*p++ = 0xec;
-	*(uint32*)p = siz;
-	p += 4;
+	if(siz > 0) {
+		mcpy(q, (byte*)&arg0, siz);
 
-	// MOVQ $q, SI
-	*p++ = 0x48;
-	*p++ = 0xbe;
-	*(byte**)p = q;
-	p += 8;
+		// SUBQ $siz, SP
+		*p++ = 0x48;
+		*p++ = 0x81;
+		*p++ = 0xec;
+		*(uint32*)p = siz;
+		p += 4;
 
-	// MOVQ SP, DI
-	*p++ = 0x48;
-	*p++ = 0x89;
-	*p++ = 0xe7;
+		// MOVQ $q, SI
+		*p++ = 0x48;
+		*p++ = 0xbe;
+		*(byte**)p = q;
+		p += 8;
 
-	if(siz <= 4*8) {
-		for(i=0; i<siz; i+=8) {
-			// MOVSQ
+		// MOVQ SP, DI
+		*p++ = 0x48;
+		*p++ = 0x89;
+		*p++ = 0xe7;
+
+		if(siz <= 4*8) {
+			for(i=0; i<siz; i+=8) {
+				// MOVSQ
+				*p++ = 0x48;
+				*p++ = 0xa5;
+			}
+		} else {
+			// MOVQ $(siz/8), CX  [32-bit immediate siz/8]
+			*p++ = 0x48;
+			*p++ = 0xc7;
+			*p++ = 0xc1;
+			*(uint32*)p = siz/8;
+			p += 4;
+
+			// REP; MOVSQ
+			*p++ = 0xf3;
 			*p++ = 0x48;
 			*p++ = 0xa5;
 		}
-	} else {
-		// MOVQ $(siz/8), CX  [32-bit immediate siz/8]
-		*p++ = 0x48;
-		*p++ = 0xc7;
-		*p++ = 0xc1;
-		*(uint32*)p = siz/8;
-		p += 4;
-
-		// REP; MOVSQ
-		*p++ = 0xf3;
-		*p++ = 0x48;
-		*p++ = 0xa5;
 	}
 
-
 	// call fn
 	pcrel = fn - (p+5);
 	if((int32)pcrel == pcrel) {
diff --git a/test/closure.go b/test/closure.go
index 97361a1..8bb516d 100644
--- a/test/closure.go
+++ b/test/closure.go
@@ -73,6 +73,10 @@
 	f(500);
 }
 
+func newfunc() (func(int) int) {
+	return func(x int) int { return x }
+}
+
 
 func main() {
 	go f();
@@ -85,4 +89,12 @@
 
 	go h();
 	check([]int{100,200,101,201,500,101,201,500});
+
+	x, y := newfunc(), newfunc();
+	if x == y {
+		panicln("newfunc returned same func");
+	}
+	if x(1) != 1 || y(2) != 2 {
+		panicln("newfunc returned broken funcs");
+	}
 }