1// runoutput
2
3// Copyright 2012 The Go Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7// Issue 3866
8// runtime.equal failed to take padding between arguments and
9// return values into account, so in certain cases gc-generated
10// code will read a random bool from the stack as the result of
11// the comparison.
12// This program generates a lot of equality tests and hopes to
13// catch this.
14// NOTE: this program assumes comparing instance of T and T's
15// underlying []byte will make gc emit calls to runtime.equal,
16// and if gc optimizes this case, then the test will no longer
17// be correct (in the sense that it no longer tests runtime.equal).
18
19package main
20
21import (
22	"bytes"
23	"fmt"
24	"strconv"
25	"strings"
26)
27
28const ntest = 1024
29
30func main() {
31	var decls, calls bytes.Buffer
32
33	for i := 1; i <= ntest; i++ {
34		s := strconv.Itoa(i)
35		decls.WriteString(strings.Replace(decl, "$", s, -1))
36		calls.WriteString(strings.Replace("call(test$)\n\t", "$", s, -1))
37	}
38
39	program = strings.Replace(program, "$DECLS", decls.String(), 1)
40	program = strings.Replace(program, "$CALLS", calls.String(), 1)
41	fmt.Print(program)
42}
43
44var program = `package main
45
46var count int
47
48func call(f func() bool) {
49	if f() {
50		count++
51	}
52}
53
54$DECLS
55
56func main() {
57	$CALLS
58	if count != 0 {
59		println("failed", count, "case(s)")
60	}
61}
62`
63
64const decl = `
65type T$ [$]uint8
66func test$() bool {
67	v := T${1}
68	return v == [$]uint8{2} || v != [$]uint8{1}
69}`
70