mirror of
https://github.com/golang/go
synced 2024-09-15 22:20:06 +00:00
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
This commit is contained in:
parent
e440354c40
commit
ae5e791ed2
|
@ -284,6 +284,7 @@ struct Node
|
||||||
NodeList* cvars; // closure params
|
NodeList* cvars; // closure params
|
||||||
NodeList* dcl; // autodcl for this func/closure
|
NodeList* dcl; // autodcl for this func/closure
|
||||||
NodeList* inl; // copy of the body for use in inlining
|
NodeList* inl; // copy of the body for use in inlining
|
||||||
|
NodeList* inldcl; // copy of dcl for use in inlining
|
||||||
|
|
||||||
// OLITERAL/OREGISTER
|
// OLITERAL/OREGISTER
|
||||||
Val val;
|
Val val;
|
||||||
|
|
|
@ -146,6 +146,7 @@ caninl(Node *fn)
|
||||||
|
|
||||||
fn->nname->inl = fn->nbody;
|
fn->nname->inl = fn->nbody;
|
||||||
fn->nbody = inlcopylist(fn->nname->inl);
|
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
|
// 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
|
// 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);
|
//dumplist("ninit pre", ninit);
|
||||||
|
|
||||||
if (fn->defn) // local function
|
if(fn->defn) // local function
|
||||||
dcl = fn->defn->dcl;
|
dcl = fn->inldcl;
|
||||||
else // imported function
|
else // imported function
|
||||||
dcl = fn->dcl;
|
dcl = fn->dcl;
|
||||||
|
|
||||||
|
|
34
test/fixedbugs/issue5515.go
Normal file
34
test/fixedbugs/issue5515.go
Normal file
|
@ -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)
|
||||||
|
}
|
Loading…
Reference in a new issue