From a72f9f46a2aacb522eb5da6bea9ea9a02a1aaea8 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Sat, 2 Feb 2013 23:17:25 -0500 Subject: [PATCH] cmd/gc: avoid duplicate allocation during inlining Fixes #4667. R=ken2 CC=golang-dev https://golang.org/cl/7275046 --- src/cmd/gc/gen.c | 2 ++ src/cmd/gc/inl.c | 7 ++++++- test/fixedbugs/issue4667.go | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 test/fixedbugs/issue4667.go diff --git a/src/cmd/gc/gen.c b/src/cmd/gc/gen.c index 8b2120253e..8114448a10 100644 --- a/src/cmd/gc/gen.c +++ b/src/cmd/gc/gen.c @@ -266,6 +266,8 @@ gen(Node *n) 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 2a61b9fecc..7b2a5ca649 100644 --- a/src/cmd/gc/inl.c +++ b/src/cmd/gc/inl.c @@ -553,6 +553,8 @@ mkinlcall1(Node **np, Node *fn, int isddd) ninit = n->ninit; +//dumplist("ninit pre", ninit); + if (fn->defn) // local function dcl = fn->defn->dcl; else // imported function @@ -566,7 +568,8 @@ mkinlcall1(Node **np, Node *fn, int isddd) 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 @@ mkinlcall1(Node **np, Node *fn, int isddd) 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 @@ mkinlcall1(Node **np, Node *fn, int isddd) 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 0000000000..3a00a31952 --- /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) + } +} -- 2.48.1