diff options
author | Dan Johnson <computerdruid@google.com> | 2018-08-15 16:48:44 -0700 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2018-08-17 15:34:50 +0000 |
commit | 876c6d1f274a3d508fa97558ca6765cf324c2939 (patch) | |
tree | 0a641a9b0bbaf79f1f51403902514d57306c7f27 | |
parent | 751ea9369a9bd3b30daafced4d1c172541076617 (diff) | |
download | go-876c6d1f274a3d508fa97558ca6765cf324c2939.tar.gz go-876c6d1f274a3d508fa97558ca6765cf324c2939.zip |
cmd/compile: make duplicate anonymous interface output deterministic
Ranging through a map is non-deterministic and there can be duplicate
entries in the set (with the same name) which don't have identical
definitions in some cases.
Fixes #27013
Change-Id: I378c48bc359c10b25b9238e0c663b498455b19fd
Reviewed-on: https://go-review.googlesource.com/129515
Reviewed-by: Russ Cox <rsc@golang.org>
-rw-r--r-- | src/cmd/compile/internal/gc/reflect.go | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/src/cmd/compile/internal/gc/reflect.go b/src/cmd/compile/internal/gc/reflect.go index b9124b6317..935c3b0503 100644 --- a/src/cmd/compile/internal/gc/reflect.go +++ b/src/cmd/compile/internal/gc/reflect.go @@ -34,8 +34,9 @@ type ptabEntry struct { // runtime interface and reflection data structures var ( - signatsetmu sync.Mutex // protects signatset + signatmu sync.Mutex // protects signatset and signatslice signatset = make(map[*types.Type]struct{}) + signatslice []*types.Type itabs []itabEntry ptabs []ptabEntry @@ -960,9 +961,9 @@ func typesymprefix(prefix string, t *types.Type) *types.Sym { // This function is for looking up type-related generated functions // (e.g. eq and hash). Make sure they are indeed generated. - signatsetmu.Lock() + signatmu.Lock() addsignat(t) - signatsetmu.Unlock() + signatmu.Unlock() //print("algsym: %s -> %+S\n", p, s); @@ -974,9 +975,9 @@ func typenamesym(t *types.Type) *types.Sym { Fatalf("typenamesym %v", t) } s := typesym(t) - signatsetmu.Lock() + signatmu.Lock() addsignat(t) - signatsetmu.Unlock() + signatmu.Unlock() return s } @@ -1447,7 +1448,10 @@ func itabsym(it *obj.LSym, offset int64) *obj.LSym { // addsignat ensures that a runtime type descriptor is emitted for t. func addsignat(t *types.Type) { - signatset[t] = struct{}{} + if _, ok := signatset[t]; !ok { + signatset[t] = struct{}{} + signatslice = append(signatslice, t) + } } func addsignats(dcls []*Node) { @@ -1462,14 +1466,15 @@ func addsignats(dcls []*Node) { func dumpsignats() { // Process signatset. Use a loop, as dtypesym adds // entries to signatset while it is being processed. - signats := make([]typeAndStr, len(signatset)) - for len(signatset) > 0 { + signats := make([]typeAndStr, len(signatslice)) + for len(signatslice) > 0 { signats = signats[:0] // Transfer entries to a slice and sort, for reproducible builds. - for t := range signatset { + for _, t := range signatslice { signats = append(signats, typeAndStr{t: t, short: typesymname(t), regular: t.String()}) delete(signatset, t) } + signatslice = signatslice[:0] sort.Sort(typesByString(signats)) for _, ts := range signats { t := ts.t |