| // 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" |
| } |