]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.15] cmd/compile: fix storeType to handle pointers to go:notinheap...
authorKeith Randall <khr@golang.org>
Thu, 22 Oct 2020 20:11:16 +0000 (13:11 -0700)
committerIan Lance Taylor <iant@golang.org>
Tue, 27 Oct 2020 23:05:53 +0000 (23:05 +0000)
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 #42151

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>
(cherry picked from commit 933721b8c7f981229974e2603850c2e9a7ffc5a1)
Reviewed-on: https://go-review.googlesource.com/c/go/+/265719
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>

src/cmd/compile/internal/gc/ssa.go
test/fixedbugs/issue42032.go [new file with mode: 0644]

index 3e21450deb5e3c3fb8e91ae96806b3b51a02fd04..7da04547c2249a5784084cfa8e85960b1ee5a601 100644 (file)
@@ -4976,7 +4976,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
@@ -5020,6 +5023,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 (file)
index 0000000..c456b1d
--- /dev/null
@@ -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")
+       }
+}