mirror of
https://github.com/golang/go
synced 2024-11-26 02:37:58 -07:00
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:
parent
f3fc8b0245
commit
366ba526e8
@ -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
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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"
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user