if fn.Func.Pragma&CgoUnsafeArgs != 0 {
s.cgoUnsafeArgs = true
}
+ if fn.Func.Pragma&Nowritebarrier != 0 {
+ s.noWB = true
+ }
+ defer func() {
+ if s.WBLineno != 0 {
+ fn.Func.WBLineno = s.WBLineno
+ }
+ }()
// TODO(khr): build config just once at the start of the compiler binary
ssaExp.log = printssa
returns []*Node
cgoUnsafeArgs bool
+ noWB bool
+ WBLineno int32 // line number of first write barrier. 0=no write barriers
}
type funcLine struct {
// } else {
// *left = *right
// }
+
+ if s.noWB {
+ s.Fatalf("write barrier prohibited")
+ }
+ if s.WBLineno == 0 {
+ s.WBLineno = left.Line
+ }
bThen := s.f.NewBlock(ssa.BlockPlain)
bElse := s.f.NewBlock(ssa.BlockPlain)
bEnd := s.f.NewBlock(ssa.BlockPlain)
// store pointer fields
// }
+ if s.noWB {
+ s.Fatalf("write barrier prohibited")
+ }
+ if s.WBLineno == 0 {
+ s.WBLineno = left.Line
+ }
s.storeTypeScalars(t, left, right)
bThen := s.f.NewBlock(ssa.BlockPlain)
return false
}
+ // No write barrier for writing a sliced slice back to its
+ // original location.
+ if (r.Op == OSLICE || r.Op == OSLICE3 || r.Op == OSLICESTR) &&
+ samesafeexpr(r.Left, l) {
+ return false
+ }
+
// Otherwise, be conservative and use write barrier.
return true
}
x.f = f17 // no barrier
x.f = func(y *T17) { *y = *x } // ERROR "write barrier"
}
+
+type T18 struct {
+ a []int
+ s string
+}
+
+func f18(p *T18, x *[]int) {
+ p.a = p.a[:5] // no barrier
+ p.a = p.a[3:5] // no barrier
+ p.a = p.a[1:2:3] // no barrier
+ p.s = p.s[8:9] // no barrier
+ *x = (*x)[3:5] // no barrier
+}