aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2016-02-12 10:07:36 -0800
committerKeith Randall <khr@golang.org>2016-02-12 21:07:21 +0000
commite3033fc535eb29ab7533ecc4a86c607c2046b9c7 (patch)
treef71a28932e72cfadcbbb3886530240b98a65cfe2
parentc93193aec0f33e901d6802e61c966286785f57ee (diff)
downloadgo-e3033fc535eb29ab7533ecc4a86c607c2046b9c7.tar.gz
go-e3033fc535eb29ab7533ecc4a86c607c2046b9c7.zip
cmd/compile: add write barrier to type switch
Type switches need write barriers if the written-to variable is heap allocated. For the added needwritebarrier call, the right arg doesn't really matter, I just pass something that will never disqualify the write barrier. The left arg is the one that matters. Fixes #14306 Change-Id: Ic2754167cce062064ea2eeac2944ea4f77cc9c3b Reviewed-on: https://go-review.googlesource.com/19481 Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
-rw-r--r--src/cmd/compile/internal/gc/gen.go2
-rw-r--r--test/writebarrier.go14
2 files changed, 15 insertions, 1 deletions
diff --git a/src/cmd/compile/internal/gc/gen.go b/src/cmd/compile/internal/gc/gen.go
index 836834f8bd..b756055668 100644
--- a/src/cmd/compile/internal/gc/gen.go
+++ b/src/cmd/compile/internal/gc/gen.go
@@ -836,7 +836,7 @@ func gen(n *Node) {
Cgen_as_wb(n.Left, n.Right, true)
case OAS2DOTTYPE:
- cgen_dottype(n.Rlist.N, n.List.N, n.List.Next.N, false)
+ cgen_dottype(n.Rlist.N, n.List.N, n.List.Next.N, needwritebarrier(n.List.N, n.Rlist.N))
case OCALLMETH:
cgen_callmeth(n, 0)
diff --git a/test/writebarrier.go b/test/writebarrier.go
index 9b741a60df..dcd20a0225 100644
--- a/test/writebarrier.go
+++ b/test/writebarrier.go
@@ -144,3 +144,17 @@ type T8 struct {
func f16(x []T8, y T8) []T8 {
return append(x, y) // ERROR "write barrier"
}
+
+func t1(i interface{}) **int {
+ // From issue 14306, make sure we have write barriers in a type switch
+ // where the assigned variable escapes.
+ switch x := i.(type) { // ERROR "write barrier"
+ case *int:
+ return &x
+ }
+ switch y := i.(type) { // no write barrier here
+ case **int:
+ return y
+ }
+ return nil
+}