cmd/gc: avoid duplicate allocation during inlining

Fixes #4667.

R=ken2
CC=golang-dev
https://golang.org/cl/7275046
diff --git a/src/cmd/gc/gen.c b/src/cmd/gc/gen.c
index 8b21202..8114448 100644
--- a/src/cmd/gc/gen.c
+++ b/src/cmd/gc/gen.c
@@ -266,6 +266,8 @@
 	Label *lab;
 	int32 wasregalloc;
 
+//dump("gen", n);
+
 	lno = setlineno(n);
 	wasregalloc = anyregalloc();
 
diff --git a/src/cmd/gc/inl.c b/src/cmd/gc/inl.c
index 2a61b9f..7b2a5ca 100644
--- a/src/cmd/gc/inl.c
+++ b/src/cmd/gc/inl.c
@@ -553,6 +553,8 @@
 
 	ninit = n->ninit;
 
+//dumplist("ninit pre", ninit);
+
 	if (fn->defn) // local function
 		dcl = fn->defn->dcl;
 	else // imported function
@@ -566,7 +568,8 @@
 			ll->n->inlvar = inlvar(ll->n);
 			// Typecheck because inlvar is not necessarily a function parameter.
 			typecheck(&ll->n->inlvar, Erv);
-			ninit = list(ninit, nod(ODCL, ll->n->inlvar, N));  // otherwise gen won't emit the allocations for heapallocs
+			if ((ll->n->class&~PHEAP) != PAUTO)
+				ninit = list(ninit, nod(ODCL, ll->n->inlvar, N));  // otherwise gen won't emit the allocations for heapallocs
 			if (ll->n->class == PPARAMOUT)  // we rely on the order being correct here
 				inlretvars = list(inlretvars, ll->n->inlvar);
 		}
@@ -733,6 +736,7 @@
 	body = list(body, nod(OLABEL, inlretlabel, N));
 
 	typechecklist(body, Etop);
+//dumplist("ninit post", ninit);
 
 	call = nod(OINLCALL, N, N);
 	call->ninit = ninit;
@@ -742,6 +746,7 @@
 	call->typecheck = 1;
 
 	setlno(call, n->lineno);
+//dumplist("call body", body);
 
 	*np = call;
 
diff --git a/test/fixedbugs/issue4667.go b/test/fixedbugs/issue4667.go
new file mode 100644
index 0000000..3a00a31
--- /dev/null
+++ b/test/fixedbugs/issue4667.go
@@ -0,0 +1,37 @@
+// run
+
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+	"fmt"
+	"os"
+	"testing"
+)
+
+var globl *int
+
+func G() {
+	F()
+}
+
+func F() {
+	var x int
+	globl = &x
+}
+
+func main() {
+	nf := testing.AllocsPerRun(100, F)
+	ng := testing.AllocsPerRun(100, G)
+	if int(nf) != 1 {
+		fmt.Printf("AllocsPerRun(100, F) = %v, want 1\n", nf)
+		os.Exit(1)
+	}
+	if int(ng) != 1 {
+		fmt.Printf("AllocsPerRun(100, G) = %v, want 1\n", ng)
+		os.Exit(1)
+	}
+}