mirror of
https://github.com/golang/go
synced 2024-11-26 04:47:57 -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) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// stkof returns n's offset from SP if n is on the stack
|
||||||
* n is on stack, either local variable
|
// (either a local variable or the return value from a function call
|
||||||
* or return value from function call.
|
// or the arguments to a function call).
|
||||||
* return n's offset from SP.
|
// 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 {
|
func stkof(n *Node) int64 {
|
||||||
switch n.Op {
|
switch n.Op {
|
||||||
case OINDREG:
|
case OINDREG:
|
||||||
|
if n.Reg != int16(Thearch.REGSP) {
|
||||||
|
return -1000 // not on stack
|
||||||
|
}
|
||||||
return n.Xoffset
|
return n.Xoffset
|
||||||
|
|
||||||
case ODOT:
|
case ODOT:
|
||||||
@ -2172,7 +2185,7 @@ func stkof(n *Node) int64 {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
off := stkof(n.Left)
|
off := stkof(n.Left)
|
||||||
if off == -1000 || off == 1000 {
|
if off == -1000 || off == +1000 {
|
||||||
return off
|
return off
|
||||||
}
|
}
|
||||||
return off + n.Xoffset
|
return off + n.Xoffset
|
||||||
@ -2183,13 +2196,13 @@ func stkof(n *Node) int64 {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
off := stkof(n.Left)
|
off := stkof(n.Left)
|
||||||
if off == -1000 || off == 1000 {
|
if off == -1000 || off == +1000 {
|
||||||
return off
|
return off
|
||||||
}
|
}
|
||||||
if Isconst(n.Right, CTINT) {
|
if Isconst(n.Right, CTINT) {
|
||||||
return off + t.Type.Width*Mpgetfix(n.Right.Val.U.(*Mpint))
|
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:
|
case OCALLMETH, OCALLINTER, OCALLFUNC:
|
||||||
t := n.Left.Type
|
t := n.Left.Type
|
||||||
@ -2210,7 +2223,7 @@ func stkof(n *Node) int64 {
|
|||||||
|
|
||||||
// botch - probably failing to recognize address
|
// botch - probably failing to recognize address
|
||||||
// arithmetic on the above. eg INDEX and DOT
|
// 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) {
|
func f14(y *[]int) {
|
||||||
*y = append(*y, 1) // ERROR "write barrier"
|
*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