aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2020-10-22 13:11:16 -0700
committerKeith Randall <khr@golang.org>2020-10-27 21:28:53 +0000
commit933721b8c7f981229974e2603850c2e9a7ffc5a1 (patch)
tree5dd7a35102cd007fb0abf6a91ae7c11e6160fcc3
parent9fcb5e0c527337c830e95d48d4574930cac53093 (diff)
downloadgo-933721b8c7f981229974e2603850c2e9a7ffc5a1.tar.gz
go-933721b8c7f981229974e2603850c2e9a7ffc5a1.zip
cmd/compile: fix storeType to handle pointers to go:notinheap types
storeType splits compound stores up into a scalar parts and a pointer parts. The scalar part happens unconditionally, and the pointer part happens under the guard of a write barrier check. Types which are declared as pointers, but are represented as scalars because they might have "bad" values, were not handled correctly here. They ended up not getting stored in either set. Fixes #42032 Change-Id: I46f6600075c0c370e640b807066247237f93c7ac Reviewed-on: https://go-review.googlesource.com/c/go/+/264300 Trust: Keith Randall <khr@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
-rw-r--r--src/cmd/compile/internal/gc/ssa.go8
-rw-r--r--test/fixedbugs/issue42032.go27
2 files changed, 34 insertions, 1 deletions
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index 4769c2c7d9..4488337924 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -5222,7 +5222,10 @@ func (s *state) storeTypeScalars(t *types.Type, left, right *ssa.Value, skip ski
case t.IsBoolean() || t.IsInteger() || t.IsFloat() || t.IsComplex():
s.store(t, left, right)
case t.IsPtrShaped():
- // no scalar fields.
+ if t.IsPtr() && t.Elem().NotInHeap() {
+ s.store(t, left, right) // see issue 42032
+ }
+ // otherwise, no scalar fields.
case t.IsString():
if skip&skipLen != 0 {
return
@@ -5266,6 +5269,9 @@ func (s *state) storeTypeScalars(t *types.Type, left, right *ssa.Value, skip ski
func (s *state) storeTypePtrs(t *types.Type, left, right *ssa.Value) {
switch {
case t.IsPtrShaped():
+ if t.IsPtr() && t.Elem().NotInHeap() {
+ break // see issue 42032
+ }
s.store(t, left, right)
case t.IsString():
ptr := s.newValue1(ssa.OpStringPtr, s.f.Config.Types.BytePtr, right)
diff --git a/test/fixedbugs/issue42032.go b/test/fixedbugs/issue42032.go
new file mode 100644
index 0000000000..c456b1db02
--- /dev/null
+++ b/test/fixedbugs/issue42032.go
@@ -0,0 +1,27 @@
+// run
+
+// Copyright 2020 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
+
+//go:notinheap
+type NIH struct {
+}
+
+type T struct {
+ x *NIH
+ p *int
+}
+
+var y NIH
+var z int
+
+func main() {
+ a := []T{{&y, &z}}
+ a = append(a, T{&y, &z})
+ if a[1].x == nil {
+ panic("pointer not written")
+ }
+}