cmd/internal/gc: add missing write barrier in append(x, BigStructWithPointers)

Fixes #10897.

Change-Id: I5c2d1f9d26333e2b2a0613ebf496daa465e07c24
Reviewed-on: https://go-review.googlesource.com/10221
Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
Russ Cox 2015-05-18 16:54:59 -04:00
parent f3fc8b0245
commit 366ba526e8
2 changed files with 38 additions and 9 deletions

View File

@ -2156,14 +2156,27 @@ func bins(typ *Type, res *Node, a, likely int, to *obj.Prog) {
}
}
/*
* n is on stack, either local variable
* or return value from function call.
* return n's offset from SP.
*/
// stkof returns n's offset from SP if n is on the stack
// (either a local variable or the return value from a function call
// or the arguments to a function call).
// If n is not on the stack, stkof returns -1000.
// If n is on the stack but in an unknown location
// (due to array index arithmetic), stkof returns +1000.
//
// NOTE(rsc): It is possible that the ODOT and OINDEX cases
// are not relevant here, since it shouldn't be possible for them
// to be involved in an overlapping copy. Only function results
// from one call and the arguments to the next can overlap in
// any non-trivial way. If they can be dropped, then this function
// becomes much simpler and also more trustworthy.
// The fact that it works at all today is probably due to the fact
// that ODOT and OINDEX are irrelevant.
func stkof(n *Node) int64 {
switch n.Op {
case OINDREG:
if n.Reg != int16(Thearch.REGSP) {
return -1000 // not on stack
}
return n.Xoffset
case ODOT:
@ -2172,7 +2185,7 @@ func stkof(n *Node) int64 {
break
}
off := stkof(n.Left)
if off == -1000 || off == 1000 {
if off == -1000 || off == +1000 {
return off
}
return off + n.Xoffset
@ -2183,13 +2196,13 @@ func stkof(n *Node) int64 {
break
}
off := stkof(n.Left)
if off == -1000 || off == 1000 {
if off == -1000 || off == +1000 {
return off
}
if Isconst(n.Right, CTINT) {
return off + t.Type.Width*Mpgetfix(n.Right.Val.U.(*Mpint))
}
return 1000
return +1000 // on stack but not sure exactly where
case OCALLMETH, OCALLINTER, OCALLFUNC:
t := n.Left.Type
@ -2210,7 +2223,7 @@ func stkof(n *Node) int64 {
// botch - probably failing to recognize address
// arithmetic on the above. eg INDEX and DOT
return -1000
return -1000 // not on stack
}
/*

View File

@ -128,3 +128,19 @@ func f13(x []int, y *[]int) {
func f14(y *[]int) {
*y = append(*y, 1) // ERROR "write barrier"
}
type T1 struct {
X *int
}
func f15(x []T1, y T1) []T1 {
return append(x, y) // ERROR "write barrier"
}
type T8 struct {
X [8]*int
}
func f16(x []T8, y T8) []T8 {
return append(x, y) // ERROR "write barrier"
}