| // errorcheck -+ -p=runtime | |
| // 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. | |
| // Test go:nowritebarrier and related directives. | |
| // This must appear to be in package runtime so the compiler | |
| // recognizes "systemstack". | |
| package runtime | |
| type t struct { | |
| f *t | |
| } | |
| var x t | |
| var y *t | |
| //go:nowritebarrier | |
| func a1() { | |
| x.f = y // ERROR "write barrier prohibited" | |
| a2() // no error | |
| } | |
| //go:noinline | |
| func a2() { | |
| x.f = y | |
| } | |
| //go:nowritebarrierrec | |
| func b1() { | |
| b2() | |
| } | |
| //go:noinline | |
| func b2() { | |
| x.f = y // ERROR "write barrier prohibited by caller" | |
| } | |
| // Test recursive cycles through nowritebarrierrec and yeswritebarrierrec. | |
| //go:nowritebarrierrec | |
| func c1() { | |
| c2() | |
| } | |
| //go:yeswritebarrierrec | |
| func c2() { | |
| c3() | |
| } | |
| func c3() { | |
| x.f = y | |
| c4() | |
| } | |
| //go:nowritebarrierrec | |
| func c4() { | |
| c2() | |
| } | |
| //go:nowritebarrierrec | |
| func d1() { | |
| d2() | |
| } | |
| func d2() { | |
| d3() | |
| } | |
| //go:noinline | |
| func d3() { | |
| x.f = y // ERROR "write barrier prohibited by caller" | |
| d4() | |
| } | |
| //go:yeswritebarrierrec | |
| func d4() { | |
| d2() | |
| } | |
| //go:noinline | |
| func systemstack(func()) {} | |
| //go:nowritebarrierrec | |
| func e1() { | |
| systemstack(e2) | |
| systemstack(func() { | |
| x.f = y // ERROR "write barrier prohibited by caller" | |
| }) | |
| } | |
| func e2() { | |
| x.f = y // ERROR "write barrier prohibited by caller" | |
| } |