}
func addsignat(t *types.Type) {
- signatlist[formalType(t)] = true
+ signatlist[t] = true
}
func addsignats(dcls []*Node) {
signats = signats[:0]
// Transfer entries to a slice and sort, for reproducible builds.
for t := range signatlist {
- signats = append(signats, typeAndStr{t: t, s: typesymname(t)})
+ signats = append(signats, typeAndStr{t: t, short: typesymname(t), regular: t.String()})
delete(signatlist, t)
}
sort.Sort(typesByString(signats))
}
type typeAndStr struct {
- t *types.Type
- s string
+ t *types.Type
+ short string
+ regular string
}
type typesByString []typeAndStr
-func (a typesByString) Len() int { return len(a) }
-func (a typesByString) Less(i, j int) bool { return a[i].s < a[j].s }
-func (a typesByString) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+func (a typesByString) Len() int { return len(a) }
+func (a typesByString) Less(i, j int) bool {
+ if a[i].short != a[j].short {
+ return a[i].short < a[j].short
+ }
+ // When the only difference between the types is whether
+ // they refer to byte or uint8, such as **byte vs **uint8,
+ // the types' ShortStrings can be identical.
+ // To preserve deterministic sort ordering, sort these by String().
+ return a[i].regular < a[j].regular
+}
+func (a typesByString) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func dalgsym(t *types.Type) *obj.LSym {
var lsym *obj.LSym
--- /dev/null
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package gc_test
+
+import (
+ "bytes"
+ "internal/testenv"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "testing"
+)
+
+func TestReproducibleBuilds(t *testing.T) {
+ testenv.MustHaveGoBuild(t)
+ iters := 10
+ if testing.Short() {
+ iters = 4
+ }
+ t.Parallel()
+ var want []byte
+ tmp, err := ioutil.TempFile("", "")
+ if err != nil {
+ t.Fatalf("temp file creation failed: %v", err)
+ }
+ defer os.Remove(tmp.Name())
+ defer tmp.Close()
+ for i := 0; i < iters; i++ {
+ out, err := exec.Command(testenv.GoToolPath(t), "tool", "compile", "-o", tmp.Name(), filepath.Join("testdata", "reproducible", "issue20272.go")).CombinedOutput()
+ if err != nil {
+ t.Fatalf("failed to compile: %v\n%s", err, out)
+ }
+ obj, err := ioutil.ReadFile(tmp.Name())
+ if err != nil {
+ t.Fatalf("failed to read object file: %v", err)
+ }
+ if i == 0 {
+ want = obj
+ } else {
+ if !bytes.Equal(want, obj) {
+ t.Fatalf("builds produced different output after %d iters (%d bytes vs %d bytes)", i, len(want), len(obj))
+ }
+ }
+ }
+}