|  | // errorcheck -+ | 
|  |  | 
|  | // 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. | 
|  |  | 
|  | package p | 
|  |  | 
|  | 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() | 
|  | } | 
|  |  | 
|  | 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" | 
|  | } |