src/cmd/gc/go.h | 1 + src/cmd/gc/inl.c | 5 +++-- test/fixedbugs/issue5515.go | 34 ++++++++++++++++++++++++++++++++++ diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 48bcf0233f13902f49a45a582871923e63643958..e94eb90eeaf34371194870e22998798fdc2919cc 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -282,6 +282,7 @@ NodeList* exit; 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 f77b51d707677c466530dc55da623f4bd1030fbe..08b462e13c5d7745471364c7cf5cb4eaf1e114ba 100644 --- a/src/cmd/gc/inl.c +++ b/src/cmd/gc/inl.c @@ -146,6 +146,7 @@ curfn = 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 @@ ninit = n->ninit; //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 0000000000000000000000000000000000000000..053abf6f7cffa18bdf000cc96efd086f405e4a2e --- /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) +}