]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: make duplicate anonymous interface output deterministic
authorDan Johnson <computerdruid@google.com>
Wed, 15 Aug 2018 23:48:44 +0000 (16:48 -0700)
committerRuss Cox <rsc@golang.org>
Fri, 17 Aug 2018 15:34:50 +0000 (15:34 +0000)
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>
src/cmd/compile/internal/gc/reflect.go

index b9124b63178a0e080c2fe8f5c21d2b2aa0dea999..935c3b05031b1b53251ac7c729c04ca980f9607a 100644 (file)
@@ -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