8000 [release-branch.go1.1] cmd/gc: save local var list before inlining · golang/go@13af44f · GitHub
[go: up one dir, main page]

Skip to content

Commit 13af44f

Browse files
committed
[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
1 parent b87a963 commit 13af44f

File tree

3 files changed

+38
-2
lines changed

3 files changed

+38
-2
lines changed

src/cmd/gc/go.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ struct Node
282282
NodeList* cvars; // closure params
283283
NodeList* dcl; // autodcl for this func/closure
284284
NodeList* inl; // copy of the body for use in inlining
285+
NodeList* inldcl; // copy of dcl for use in inlining
285286

286287
// OLITERAL/OREGISTER
287288
Val val;

src/cmd/gc/inl.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ caninl(Node *fn)
146146

147147
fn->nname->inl = fn->nbody;
148148
fn->nbody = inlcopylist(fn->nname->inl);
149+
fn->nname->inldcl = inlcopylist(fn->nname->defn->dcl);
149150

150151
// hack, TODO, check for better way to link method nodes back to the thing with the ->inl
151152
// this is so export can find the body of a method
@@ -558,8 +559,8 @@ mkinlcall1(Node **np, Node *fn, int isddd)
558559

559560
//dumplist("ninit pre", ninit);
560561

561-
if (fn->defn) // local function
562-
dcl = fn->defn->dcl;
562+
if(fn->defn) // local function
563+
dcl = fn->inldcl;
563564
else // imported function
564565
dcl = fn->dcl;
565566

test/fixedbugs/issue5515.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// run
2+
3+
// Copyright 2013 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
// issue 5515: miscompilation doing inlining in generated method wrapper
8+
9+
package main
10+
11+
type T uint32
12+
13+
func main() {
14+
b := make([]T, 8)
15+
b[0] = 0xdeadbeef
16+
rs := Slice(b)
17+
sort(rs)
18+
}
19+
20+
type Slice []T
21+
22+
func (s Slice) Swap(i, j int) {
23+
tmp := s[i]
24+
s[i] = s[j]
25+
s[j] = tmp
26+
}
27+
28+
type Interface interface {
29+
Swap(i, j int)
30+
}
31+
32+
func sort(data Interface) {
33+
data.Swap(0, 4)
34+
}

0 commit comments

Comments
 (0)
0