]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.8] cmd/compile: do not use "oaslit" for global
authorCherry Zhang <cherryyz@google.com>
Mon, 6 Feb 2017 19:24:16 +0000 (14:24 -0500)
committerCherry Zhang <cherryyz@google.com>
Tue, 7 Feb 2017 17:39:16 +0000 (17:39 +0000)
The compiler did not emit write barrier for assigning global with
struct literal, like global = T{} where T contains pointer.

The relevant code path is:
walkexpr OAS var_ OSTRUCTLIT
    oaslit
        anylit OSTRUCTLIT
            walkexpr OAS var_ nil
            return without adding write barrier
    return true
break (without adding write barrier)

This CL makes oaslit not apply to globals. See also CL
https://go-review.googlesource.com/c/36355/ for an alternative
fix.

The downside of this is that it generates static data for zeroing
struct now. Also this only covers global. If there is any lurking
bug with implicit zeroing other than globals, this doesn't fix.

Fixes #18956.

Change-Id: Ibcd27e4fae3aa38390ffa94a32a9dd7a802e4b37
Reviewed-on: https://go-review.googlesource.com/36410
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
(cherry picked from commit 160914e33ca6521d74297291d801062cc44d794d)
Reviewed-on: https://go-review.googlesource.com/36531

src/cmd/compile/internal/gc/sinit.go
test/writebarrier.go

index 6b3c426ca3724b1a06fbbf008670af82bbb54c5b..416e2b252beedcf53e036545c50f2a3c3eeaa5f6 100644 (file)
@@ -585,7 +585,7 @@ func isliteral(n *Node) bool {
 }
 
 func (n *Node) isSimpleName() bool {
-       return n.Op == ONAME && n.Addable && n.Class != PAUTOHEAP
+       return n.Op == ONAME && n.Addable && n.Class != PAUTOHEAP && n.Class != PEXTERN
 }
 
 func litas(l *Node, r *Node, init *Nodes) {
index 6460a6f9daeed56a9c481a4bfe947329b404c164..13f7b546084e20ee7675ac53f58cd9f0ed2c5867 100644 (file)
@@ -220,3 +220,19 @@ func f22(x *int) (y *int) {
        *p = x // no barrier
        return
 }
+
+type T23 struct {
+       p *int
+       a int
+}
+
+var t23 T23
+var i23 int
+
+func f23() {
+       // zeroing global needs write barrier for the hybrid barrier.
+       t23 = T23{} // ERROR "write barrier"
+       // also test partial assignments
+       t23 = T23{a: 1}    // ERROR "write barrier"
+       t23 = T23{p: &i23} // ERROR "write barrier"
+}