From ae5e791ed20076bf67e5da20fee769ec86a7a969 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 11 Jun 2013 20:23:21 -0700 Subject: [PATCH] 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 --- 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 2f2d90391c4..fa062d65234 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -284,6 +284,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 bbb887be23c..6800884a0be 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 @@ -559,8 +560,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 00000000000..053abf6f7cf --- /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) +}