]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: On a runtime.KeepAlive call, keep whole variable alive
authorKeith Randall <khr@golang.org>
Tue, 1 Nov 2016 04:18:00 +0000 (21:18 -0700)
committerKeith Randall <khr@golang.org>
Wed, 2 Nov 2016 21:29:41 +0000 (21:29 +0000)
We generate an OpKeepAlive for the idata portion of the interface
for a runtime.KeepAlive call.  But given such an op, we need to keep
the entire containing variable alive, not just the range that was
passed to the OpKeepAlive operation.

Fixes #17710

Change-Id: I90de66ec8065e22fb09bcf9722999ddda289ae6e
Reviewed-on: https://go-review.googlesource.com/32477
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
src/cmd/compile/internal/gc/ssa.go
test/fixedbugs/issue17710.go [new file with mode: 0644]

index ea9fc5b845ac717f3ac5773baa47c160c1493377..b77dafd3459ed494640a71693cdc4bccf285befa 100644 (file)
@@ -4399,13 +4399,14 @@ func KeepAlive(v *ssa.Value) {
        if !v.Args[0].Type.IsPtrShaped() {
                v.Fatalf("keeping non-pointer alive %v", v.Args[0])
        }
-       n, off := AutoVar(v.Args[0])
+       n, _ := AutoVar(v.Args[0])
        if n == nil {
                v.Fatalf("KeepAlive with non-spilled value %s %s", v, v.Args[0])
        }
-       if off != 0 {
-               v.Fatalf("KeepAlive with non-zero offset spill location %v:%d", n, off)
-       }
+       // Note: KeepAlive arg may be a small part of a larger variable n.  We keep the
+       // whole variable n alive at this point. (Typically, this happens when
+       // we are requested to keep the idata portion of an interface{} alive, and
+       // we end up keeping the whole interface{} alive.  That's ok.)
        Gvarlive(n)
 }
 
diff --git a/test/fixedbugs/issue17710.go b/test/fixedbugs/issue17710.go
new file mode 100644 (file)
index 0000000..2843458
--- /dev/null
@@ -0,0 +1,13 @@
+// compile
+
+// Copyright 2016 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.
+
+package main
+
+import "runtime"
+
+func f(x interface{}) {
+       runtime.KeepAlive(x)
+}