go/ssa: use sync.Once instead of sync.atomic
This adds a missing memory barrier at the end of Package.Build.
Change-Id: Ife35d5ad5a48ba121f35656fef682863d4f2aef6
Reviewed-on: https://go-review.googlesource.com/14761
Reviewed-by: Robert Griesemer <gri@golang.org>
diff --git a/go/ssa/builder.go b/go/ssa/builder.go
index c2a4a89..3f760d2 100644
--- a/go/ssa/builder.go
+++ b/go/ssa/builder.go
@@ -35,7 +35,6 @@
"go/token"
"os"
"sync"
- "sync/atomic"
"golang.org/x/tools/go/exact"
"golang.org/x/tools/go/types"
@@ -2241,10 +2240,9 @@
//
// Build is idempotent and thread-safe.
//
-func (p *Package) Build() {
- if !atomic.CompareAndSwapInt32(&p.started, 0, 1) {
- return // already started
- }
+func (p *Package) Build() { p.buildOnce.Do(p.build) }
+
+func (p *Package) build() {
if p.info == nil {
return // synthetic package, e.g. "testmain"
}
diff --git a/go/ssa/ssa.go b/go/ssa/ssa.go
index b24c195..6ea33f5 100644
--- a/go/ssa/ssa.go
+++ b/go/ssa/ssa.go
@@ -53,10 +53,10 @@
// The following fields are set transiently, then cleared
// after building.
- started int32 // atomically tested and set at start of build phase
- ninit int32 // number of init functions
- info *types.Info // package type information
- files []*ast.File // package ASTs
+ buildOnce sync.Once // ensures package building occurs once
+ ninit int32 // number of init functions
+ info *types.Info // package type information
+ files []*ast.File // package ASTs
}
// A Member is a member of a Go package, implemented by *NamedConst,