From 13af44f8a57bb045f8ce7fc4207124329eac2438 Mon Sep 17 00:00:00 2001 From: Andrew Gerrand Date: Thu, 13 Jun 2013 10:04:17 +1000 Subject: [release-branch.go1.1] cmd/gc: save local var list before inlining MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ««« CL 10210043 / b357e33bb414 cmd/gc: save local var list before inlining This avoids problems with inlining in genwrappers, which occurs after functions have been compiled. Compiling a function may cause some unused local vars to be removed from the list. Since a local var may be unused due to optimization, it is possible that a removed local var winds up beingused in the inlined version, in which case hilarity ensues. Fixes #5515. R=golang-dev, khr, dave CC=golang-dev https://golang.org/cl/10210043 »»» R=iant, rsc CC=golang-dev https://golang.org/cl/10242044 --- src/cmd/gc/go.h | 1 + src/cmd/gc/inl.c | 5 +++-- test/fixedbugs/issue5515.go | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 test/fixedbugs/issue5515.go diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 48bcf0233f..e94eb90eea 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -282,6 +282,7 @@ struct Node NodeList* cvars; // closure params NodeList* dcl; // autodcl for this func/closure NodeList* inl; // copy of the body for use in inlining + NodeList* inldcl; // copy of dcl for use in inlining // OLITERAL/OREGISTER Val val; diff --git a/src/cmd/gc/inl.c b/src/cmd/gc/inl.c index f77b51d707..08b462e13c 100644 --- a/src/cmd/gc/inl.c +++ b/src/cmd/gc/inl.c @@ -146,6 +146,7 @@ caninl(Node *fn) fn->nname->inl = fn->nbody; fn->nbody = inlcopylist(fn->nname->inl); + fn->nname->inldcl = inlcopylist(fn->nname->defn->dcl); // hack, TODO, check for better way to link method nodes back to the thing with the ->inl // this is so export can find the body of a method @@ -558,8 +559,8 @@ mkinlcall1(Node **np, Node *fn, int isddd) //dumplist("ninit pre", ninit); - if (fn->defn) // local function - dcl = fn->defn->dcl; + if(fn->defn) // local function + dcl = fn->inldcl; else // imported function dcl = fn->dcl; diff --git a/test/fixedbugs/issue5515.go b/test/fixedbugs/issue5515.go new file mode 100644 index 0000000000..053abf6f7c --- /dev/null +++ b/test/fixedbugs/issue5515.go @@ -0,0 +1,34 @@ +// 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. + +// issue 5515: miscompilation doing inlining in generated method wrapper + +package main + +type T uint32 + +func main() { + b := make([]T, 8) + b[0] = 0xdeadbeef + rs := Slice(b) + sort(rs) +} + +type Slice []T + +func (s Slice) Swap(i, j int) { + tmp := s[i] + s[i] = s[j] + s[j] = tmp +} + +type Interface interface { + Swap(i, j int) +} + +func sort(data Interface) { + data.Swap(0, 4) +} -- cgit v1.2.3-54-g00ecf