]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.1] cmd/gc: save local var list before inlining
authorAndrew Gerrand <adg@golang.org>
Thu, 13 Jun 2013 00:04:17 +0000 (10:04 +1000)
committerAndrew Gerrand <adg@golang.org>
Thu, 13 Jun 2013 00:04:17 +0000 (10:04 +1000)
««« 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

src/cmd/gc/go.h
src/cmd/gc/inl.c
test/fixedbugs/issue5515.go [new file with mode: 0644]

index 48bcf0233f13902f49a45a582871923e63643958..e94eb90eeaf34371194870e22998798fdc2919cc 100644 (file)
@@ -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;
index f77b51d707677c466530dc55da623f4bd1030fbe..08b462e13c5d7745471364c7cf5cb4eaf1e114ba 100644 (file)
@@ -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 (file)
index 0000000..053abf6
--- /dev/null
@@ -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)
+}