diff options
author | Andrew Gerrand <adg@golang.org> | 2013-06-13 10:04:17 +1000 |
---|---|---|
committer | Andrew Gerrand <adg@golang.org> | 2013-06-13 10:04:17 +1000 |
commit | 13af44f8a57bb045f8ce7fc4207124329eac2438 (patch) | |
tree | e4120b491a89da0d45461a5fcbd2f53012d19a54 | |
parent | b87a963f876d258af844d6a293ea0c3ed80b3407 (diff) | |
download | go-13af44f8a57bb045f8ce7fc4207124329eac2438.tar.gz go-13af44f8a57bb045f8ce7fc4207124329eac2438.zip |
[release-branch.go1.1] cmd/gc: save local var list before inlining
««« 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
-rw-r--r-- | src/cmd/gc/go.h | 1 | ||||
-rw-r--r-- | src/cmd/gc/inl.c | 5 | ||||
-rw-r--r-- | test/fixedbugs/issue5515.go | 34 |
3 files changed, 38 insertions, 2 deletions
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) +} |