Commit 42da35c6 authored by Keith Randall's avatar Keith Randall

cmd/compile: SSA, don't let write barrier clobber return values

When we do *p = f(), we might need to copy the return value from
f to p with a write barrier.  The write barrier itself is a call,
so we need to copy the return value of f to a temporary location
before we call the write barrier function.  Otherwise, the call
itself (specifically, marshalling the args to typedmemmove) will
clobber the value we're trying to write.

Fixes #15854

Change-Id: I5703da87634d91a9884e3ec098d7b3af713462e7
Reviewed-on: https://go-review.googlesource.com/23522Reviewed-by: 's avatarDavid Chase <drchase@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 3a6a4186
// Copyright 2016 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 gc
import "testing"
type T struct {
x [2]int64 // field that will be clobbered. Also makes type not SSAable.
p *byte // has a pointer
}
//go:noinline
func makeT() T {
return T{}
}
var g T
var sink []byte
func TestIssue15854(t *testing.T) {
for i := 0; i < 10000; i++ {
if g.x[0] != 0 {
t.Fatalf("g.x[0] clobbered with %x\n", g.x[0])
}
// The bug was in the following assignment. The return
// value of makeT() is not copied out of the args area of
// stack frame in a timely fashion. So when write barriers
// are enabled, the marshaling of the args for the write
// barrier call clobbers the result of makeT() before it is
// read by the write barrier code.
g = makeT()
sink = make([]byte, 1000) // force write barriers to eventually happen
}
}
func TestIssue15854b(t *testing.T) {
const N = 10000
a := make([]T, N)
for i := 0; i < N; i++ {
a = append(a, makeT())
sink = make([]byte, 1000) // force write barriers to eventually happen
}
for i, v := range a {
if v.x[0] != 0 {
t.Fatalf("a[%d].x[0] clobbered with %x\n", i, v.x[0])
}
}
}
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment