Skip to content

Commit

Permalink
[release-branch.go1.15] cmd/compile: fix storeType to handle pointers…
Browse files Browse the repository at this point in the history
… 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 #42151

Change-Id: I46f6600075c0c370e640b807066247237f93c7ac
Reviewed-on: https://go-review.googlesource.com/c/go/+/264300
Trust: Keith Randall <[email protected]>
Reviewed-by: Ian Lance Taylor <[email protected]>
(cherry picked from commit 933721b)
Reviewed-on: https://go-review.googlesource.com/c/go/+/265719
Run-TryBot: Keith Randall <[email protected]>
TryBot-Result: Go Bot <[email protected]>
  • Loading branch information
randall77 authored and ianlancetaylor committed Oct 27, 2020
1 parent 255afa2 commit 068911e
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/cmd/compile/internal/gc/ssa.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
27 changes: 27 additions & 0 deletions test/fixedbugs/issue42032.go
Original file line number Diff line number Diff line change
@@ -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")
}
}

0 comments on commit 068911e

Please sign in to comment.