Commit be66a226 by Ian Lance Taylor Committed by Ian Lance Taylor

Update Go testsuite to a copy of the Go 1.1.2 testsuite.

	* go.test/go-test.exp (go-find-packages): New proc.
	(go-gc-tests): Skip stress and safe tests.  Skip *.dir
	subdirectories.  Do simple +build line matching.  Handle run with
	arguments.  Handle errorcheckdir and rundircmpout.  Use packages
	for rundir.  Remove special handling for bug191 and dwarf.

From-SVN: r203578
parent 8088e1be
2013-10-14 Ian Lance Taylor <iant@google.com>
* go.test/go-test.exp (go-find-packages): New proc.
(go-gc-tests): Skip stress and safe tests. Skip *.dir
subdirectories. Do simple +build line matching. Handle run with
arguments. Handle errorcheckdir and rundircmpout. Use packages
for rundir. Remove special handling for bug191 and dwarf.
2013-10-14 Tobias Burnus <burnus@net-b.de> 2013-10-14 Tobias Burnus <burnus@net-b.de>
PR fortran/58658 PR fortran/58658
......
...@@ -242,6 +242,42 @@ proc go-set-goarch { } { ...@@ -242,6 +242,42 @@ proc go-set-goarch { } {
setenv GOARCH $goarch setenv GOARCH $goarch
} }
# Take a list of files and return a lists of lists, where each list is
# the set of files in the same package.
proc go-find-packages { test name files } {
set packages [list]
foreach f $files {
set fd [open $f r]
while 1 {
if { [gets $fd line] < 0 } {
close $fd
clone_output "$test: could not read $f"
unresolved $name
return [list]
}
if { [regexp "^package (\\w+)" $line match package] } {
set len [llength $packages]
for { set i 0 } { $i < $len } { incr i } {
set p [lindex $packages $i]
if { [lindex $p 0] == $package } {
lappend p $f
lset packages $i $p
break
}
}
if { $i >= $len } {
lappend packages [list $package $f]
}
close $fd
break
}
}
}
return $packages
}
proc go-gc-tests { } { proc go-gc-tests { } {
global srcdir subdir global srcdir subdir
global runtests global runtests
...@@ -286,12 +322,28 @@ proc go-gc-tests { } { ...@@ -286,12 +322,28 @@ proc go-gc-tests { } {
continue continue
} }
# Skip the files in stress; they are not tests.
if [string match "*go.test/test/stress/*" $test] {
continue
}
# Skip the files in safe; gccgo does not support safe mode.
if [string match "*go.test/test/safe/*" $test] {
continue
}
# Skip files in sub-subdirectories: they are components of # Skip files in sub-subdirectories: they are components of
# other tests. # other tests.
if [string match "*go.test/test/*/*/*" $test] { if [string match "*go.test/test/*/*/*" $test] {
continue continue
} }
# Skip files in *.dir subdirectories: they are components of
# other tests.
if [string match "*go.test/test/*.dir/*" $test] {
continue
}
set name [dg-trim-dirname $srcdir $test] set name [dg-trim-dirname $srcdir $test]
# Skip certain tests if target is RTEMS OS. # Skip certain tests if target is RTEMS OS.
...@@ -379,6 +431,21 @@ proc go-gc-tests { } { ...@@ -379,6 +431,21 @@ proc go-gc-tests { } {
continue continue
} }
if { [ string match "// +build *" $test_line ] } {
if { [ string match "*[getenv GOARCH]*" $test_line ] } {
continue
}
if { [ string match "*linux*" $test_line ] } {
continue
}
if { [ string match "*!windows*" $test_line ] } {
continue
}
close $fd
unsupported $name
set lines_ok 0
}
break break
} }
...@@ -407,7 +474,8 @@ proc go-gc-tests { } { ...@@ -407,7 +474,8 @@ proc go-gc-tests { } {
set go_compile_args "" set go_compile_args ""
set go_execute_args "" set go_execute_args ""
if { [regexp ".*\\\$A.out (\[^|&>2\].*)\$" $test_line match progargs] } { if { [regexp "// run (\[^|&>2\].*)\$" $test_line match progargs] \
&& ! [string match "*.go*" "$progargs"] } {
set go_execute_args $progargs set go_execute_args $progargs
verbose -log "$test: go_execute_args is $go_execute_args" verbose -log "$test: go_execute_args is $go_execute_args"
set index [string last " $progargs" $test_line] set index [string last " $progargs" $test_line]
...@@ -515,6 +583,27 @@ proc go-gc-tests { } { ...@@ -515,6 +583,27 @@ proc go-gc-tests { } {
go-execute-xfail $test go-execute-xfail $test
} elseif { $test_line == "// errorcheck" } { } elseif { $test_line == "// errorcheck" } {
errchk $test "" errchk $test ""
} elseif { $test_line == "// errorcheckdir" } {
set hold_runtests $runtests
set runtests "go-test.exp"
set dir "[file rootname $test].dir"
set files [lsort [glob "$dir/*.go"]]
set packages [go-find-packages $test $name $files]
if { [llength $packages] > 0 } {
set dg-do-what-default "assemble"
set del [list]
set last [lindex $packages end]
set packages [lreplace $packages end end]
foreach p $packages {
dg-test -keep-output [lrange $p 1 end] "-O" "-w $DEFAULT_GOCFLAGS"
lappend del "[file rootname [file tail [lindex $p 1]]].o"
}
errchk [lindex $last 1] "[lrange $last 2 end]"
foreach f $del {
file delete $f
}
}
set runtests $hold_runtests
} elseif { [string match "// errorcheckoutput*" $test_line] } { } elseif { [string match "// errorcheckoutput*" $test_line] } {
# Run the test to get a .go program to error check. # Run the test to get a .go program to error check.
set go_execute_args "" set go_execute_args ""
...@@ -557,21 +646,62 @@ proc go-gc-tests { } { ...@@ -557,21 +646,62 @@ proc go-gc-tests { } {
} elseif { $test_line == "// rundir" } { } elseif { $test_line == "// rundir" } {
set hold_runtests $runtests set hold_runtests $runtests
set runtests "go-test.exp" set runtests "go-test.exp"
set dg-do-what-default "assemble"
set dir "[file rootname $test].dir" set dir "[file rootname $test].dir"
set del {}
set files [lsort [glob "$dir/*.go"]] set files [lsort [glob "$dir/*.go"]]
set last [lindex $files end] set packages [go-find-packages $test $name $files]
set files [lreplace $files end end] if { [llength $packages] > 0 } {
foreach f $files { set dg-do-what-default "assemble"
dg-test -keep-output $f "-O" "-w $DEFAULT_GOCFLAGS" set del [list]
lappend del "[file rootname [file tail $f]].o" set last [lindex $packages end]
set packages [lreplace $packages end end]
foreach p $packages {
dg-test -keep-output [lrange $p 1 end] "-O" "-w $DEFAULT_GOCFLAGS"
lappend del "[file rootname [file tail [lindex $p 1]]].o"
}
set dg-do-what-default "link"
set go_compile_args $del
go-torture-execute [lrange $last 1 end]
foreach f $del {
file delete $f
}
} }
set dg-do-what-default "link" set runtests $hold_runtests
set go_compile_args $del } elseif { $test_line == "// rundircmpout" } {
go-torture-execute $last set hold_runtests $runtests
foreach f $del { set runtests "go-test.exp"
file delete $f set dir "[file rootname $test].dir"
set files [lsort [glob "$dir/*.go"]]
set packages [go-find-packages $test $name $files]
if { [llength $packages] > 0 } {
set dg-do-what-default "assemble"
set del [list]
set last [lindex $packages end]
set packages [lreplace $packages end end]
foreach p $packages {
dg-test -keep-output [lrange $p 1 end] "-O" "-w $DEFAULT_GOCFLAGS"
lappend del "[file rootname [file tail [lindex $p 1]]].o"
}
set dg-do-what-default "link"
dg-test -keep-output [lrange $last 1 end] "$del -O" "-w $DEFAULT_GOCFLAGS"
set base "[file rootname [file tail [lindex $last 1]]]"
set output_file "./$base.exe"
lappend del $output_file
if [isnative] {
verbose -log "$output_file >$base.p 2>&1"
if { [catch "exec $output_file 2>$base.p" catcherr] != 0 } {
verbose -log $catcherr
fail "$name execution"
untested "$name compare"
} else {
pass "$name execution"
regsub "\\.go$" "$test" ".out" expect
filecmp $expect $base.p "$name compare"
}
lappend del $base.p
}
foreach f $del {
file delete $f
}
} }
set runtests $hold_runtests set runtests $hold_runtests
} elseif { "$test_line" == "" } elseif { "$test_line" == ""
...@@ -709,33 +839,6 @@ proc go-gc-tests { } { ...@@ -709,33 +839,6 @@ proc go-gc-tests { } {
file delete $ofile1 $ofile2 $ofile3 $output_file file delete $ofile1 $ofile2 $ofile3 $output_file
set runtests $hold_runtests set runtests $hold_runtests
} elseif { [string match \ } elseif { [string match \
"// \$G \$D/bug191.dir/a.go && \$G \$D/bug191.dir/b.go && \$G \$D/\$F.go && \$L \$F.\$A" \
$test_line] } {
set hold_runtests $runtests
set runtests "go-test.exp"
set dg-do-what-default "assemble"
regsub "\\.go$" $test ".dir/a.go" file1
dg-test -keep-output $file1 "-O" "-w $DEFAULT_GOCFLAGS"
set ofile1 "[file rootname [file tail $file1]].o"
regsub "\\.go$" $test ".dir/b.go" file2
dg-test -keep-output $file2 "-O" "-w $DEFAULT_GOCFLAGS"
set ofile2 "[file rootname [file tail $file2]].o"
dg-test -keep-output "$test" "-O" "-w $DEFAULT_GOCFLAGS"
set ofile3 "[file rootname [file tail $test]].o"
set dg-do-what-default "link"
set output_file "./[file rootname [file tail $test]].exe"
set comp_output [go_target_compile "$ofile1 $ofile2 $ofile3" \
$output_file "executable" "$options"]
set comp_output [go-dg-prune $target_triplet $comp_output]
if [string match "" $comp_output] {
pass $name
} else {
verbose -log $comp_output
fail $name
}
file delete $ofile1 $ofile2 $ofile3 $output_file
set runtests $hold_runtests
} elseif { [string match \
"// \$G \$D/embed0.go && \$G \$D/\$F.go && \$L \$F.\$A && ./\$A.out" \ "// \$G \$D/embed0.go && \$G \$D/\$F.go && \$L \$F.\$A && ./\$A.out" \
$test_line ] } { $test_line ] } {
set hold_runtests $runtests set hold_runtests $runtests
...@@ -949,10 +1052,6 @@ proc go-gc-tests { } { ...@@ -949,10 +1052,6 @@ proc go-gc-tests { } {
regsub "\\.go$" $test ".dir/a.go" file1 regsub "\\.go$" $test ".dir/a.go" file1
regsub "\\.go$" $test ".dir/b.go" file2 regsub "\\.go$" $test ".dir/b.go" file2
errchk "$file1" "$file2" errchk "$file1" "$file2"
} elseif { $test_line == "// \$G \$D/\$F.go \$D/z*.go && \$L \$F.\$A && ./\$A.out" } {
set dir [file dirname $test]
set go_compile_args [glob $dir/z*.go]
go-torture-execute $test
} elseif { $test_line == "// \$G -N -o slow.\$A \$D/bug369.dir/pkg.go &&" \ } elseif { $test_line == "// \$G -N -o slow.\$A \$D/bug369.dir/pkg.go &&" \
&& $test_line2 == "// \$G -o fast.\$A \$D/bug369.dir/pkg.go &&" \ && $test_line2 == "// \$G -o fast.\$A \$D/bug369.dir/pkg.go &&" \
&& $test_line3 == "// run" } { && $test_line3 == "// run" } {
......
...@@ -17,7 +17,7 @@ func main() { ...@@ -17,7 +17,7 @@ func main() {
case uint8: case uint8:
// ok // ok
default: default:
println("byte != uint8") panic("byte != uint8")
} }
x = uint8(2) x = uint8(2)
...@@ -25,7 +25,7 @@ func main() { ...@@ -25,7 +25,7 @@ func main() {
case byte: case byte:
// ok // ok
default: default:
println("uint8 != byte") panic("uint8 != byte")
} }
rune32 := false rune32 := false
...@@ -37,7 +37,7 @@ func main() { ...@@ -37,7 +37,7 @@ func main() {
// must be new code // must be new code
rune32 = true rune32 = true
default: default:
println("rune != int and rune != int32") panic("rune != int and rune != int32")
} }
if rune32 { if rune32 {
...@@ -49,6 +49,6 @@ func main() { ...@@ -49,6 +49,6 @@ func main() {
case rune: case rune:
// ok // ok
default: default:
println("int (or int32) != rune") panic("int (or int32) != rune")
} }
} }
// $G $F.go && $L $F.$A && ./$A.out arg1 arg2 // run arg1 arg2
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
......
...@@ -134,20 +134,31 @@ func main() { ...@@ -134,20 +134,31 @@ func main() {
} }
} }
// find . -type d -not -path "./exp" -not -path "./exp/*" -printf "\t\"%p\",\n" | sort | sed "s/\.\///" | grep -v testdata
var packages = []string{ var packages = []string{
"archive",
"archive/tar", "archive/tar",
"encoding/asn1", "archive/zip",
"math/big",
"bufio", "bufio",
"builtin",
"bytes", "bytes",
"math/cmplx", "compress",
"compress/bzip2",
"compress/flate", "compress/flate",
"compress/gzip", "compress/gzip",
"compress/lzw",
"compress/zlib", "compress/zlib",
"container",
"container/heap", "container/heap",
"container/list", "container/list",
"container/ring", "container/ring",
"crypto",
"crypto/aes", "crypto/aes",
"crypto/cipher",
"crypto/des",
"crypto/dsa",
"crypto/ecdsa",
"crypto/elliptic",
"crypto/hmac", "crypto/hmac",
"crypto/md5", "crypto/md5",
"crypto/rand", "crypto/rand",
...@@ -159,64 +170,111 @@ var packages = []string{ ...@@ -159,64 +170,111 @@ var packages = []string{
"crypto/subtle", "crypto/subtle",
"crypto/tls", "crypto/tls",
"crypto/x509", "crypto/x509",
"crypto/x509/pkix",
"database",
"database/sql",
"database/sql/driver",
"debug",
"debug/dwarf", "debug/dwarf",
"debug/macho",
"debug/elf", "debug/elf",
"debug/gosym", "debug/gosym",
"exp/ebnf", "debug/macho",
"debug/pe",
"encoding",
"encoding/ascii85", "encoding/ascii85",
"encoding/asn1",
"encoding/base32",
"encoding/base64", "encoding/base64",
"encoding/binary", "encoding/binary",
"encoding/csv",
"encoding/gob",
"encoding/hex", "encoding/hex",
"encoding/json",
"encoding/pem", "encoding/pem",
"os/exec", "encoding/xml",
"errors",
"expvar",
"flag", "flag",
"fmt", "fmt",
"go",
"go/ast", "go/ast",
"go/build",
"go/doc", "go/doc",
"go/format",
"go/parser", "go/parser",
"go/printer", "go/printer",
"go/scanner", "go/scanner",
"go/token", "go/token",
"encoding/gob",
"hash", "hash",
"hash/adler32", "hash/adler32",
"hash/crc32", "hash/crc32",
"hash/crc64", "hash/crc64",
"net/http", "hash/fnv",
"html",
"html/template",
"image", "image",
"image/color",
"image/draw",
"image/gif",
"image/jpeg", "image/jpeg",
"image/png", "image/png",
"index",
"index/suffixarray",
"io", "io",
"io/ioutil", "io/ioutil",
"encoding/json",
"log", "log",
"log/syslog",
"math", "math",
"math/big",
"math/cmplx",
"math/rand",
"mime", "mime",
"mime/multipart",
"net", "net",
"net/http",
"net/http/cgi",
"net/http/cookiejar",
"net/http/fcgi",
"net/http/httptest",
"net/http/httputil",
"net/http/pprof",
"net/mail",
"net/rpc",
"net/rpc/jsonrpc",
"net/smtp",
"net/textproto",
"net/url",
"os", "os",
"os/exec",
"os/signal",
"os/user",
"path", "path",
"math/rand", "path/filepath",
"reflect", "reflect",
"regexp", "regexp",
"net/rpc", "regexp/syntax",
"runtime", "runtime",
"text/scanner", "runtime/cgo",
"runtime/debug",
"runtime/pprof",
"runtime/race",
"sort", "sort",
"net/smtp",
"strconv", "strconv",
"strings", "strings",
"sync", "sync",
"sync/atomic",
"syscall", "syscall",
"log/syslog",
"text/tabwriter",
"text/template",
"testing", "testing",
"testing/iotest", "testing/iotest",
"testing/quick", "testing/quick",
"text",
"text/scanner",
"text/tabwriter",
"text/template",
"text/template/parse",
"time", "time",
"unicode", "unicode",
"unicode/utf8",
"unicode/utf16", "unicode/utf16",
"encoding/xml", "unicode/utf8",
"unsafe",
} }
// Copyright 2013 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 go1
// benchmark based on fmt/fmt_test.go
import (
"bytes"
"fmt"
"testing"
)
func BenchmarkFmtFprintfEmpty(b *testing.B) {
var buf bytes.Buffer
for i := 0; i < b.N; i++ {
fmt.Fprintf(&buf, "")
}
}
func BenchmarkFmtFprintfString(b *testing.B) {
var buf bytes.Buffer
for i := 0; i < b.N; i++ {
buf.Reset()
fmt.Fprintf(&buf, "%s", "hello")
}
}
func BenchmarkFmtFprintfInt(b *testing.B) {
var buf bytes.Buffer
for i := 0; i < b.N; i++ {
buf.Reset()
fmt.Fprintf(&buf, "%d", 5)
}
}
func BenchmarkFmtFprintfIntInt(b *testing.B) {
var buf bytes.Buffer
for i := 0; i < b.N; i++ {
buf.Reset()
fmt.Fprintf(&buf, "%d %d", 5, 6)
}
}
func BenchmarkFmtFprintfPrefixedInt(b *testing.B) {
var buf bytes.Buffer
for i := 0; i < b.N; i++ {
buf.Reset()
fmt.Fprintf(&buf, "This is some meaningless prefix text that needs to be scanned %d", 6)
}
}
func BenchmarkFmtFprintfFloat(b *testing.B) {
var buf bytes.Buffer
for i := 0; i < b.N; i++ {
buf.Reset()
fmt.Fprintf(&buf, "%g", 5.23184)
}
}
func BenchmarkFmtManyArgs(b *testing.B) {
var buf bytes.Buffer
for i := 0; i < b.N; i++ {
buf.Reset()
fmt.Fprintf(&buf, "%2d/%2d/%2d %d:%d:%d %s %s\n", 3, 4, 5, 11, 12, 13, "hello", "world")
}
}
// Copyright 2013 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 go1
import (
"bytes"
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"
)
// BenchmarkHTTPClientServer benchmarks both the HTTP client and the HTTP server,
// on small requests.
func BenchmarkHTTPClientServer(b *testing.B) {
msg := []byte("Hello world.\n")
ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
rw.Write(msg)
}))
defer ts.Close()
tr := &http.Transport{}
defer tr.CloseIdleConnections()
cl := &http.Client{
Transport: tr,
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
res, err := cl.Get(ts.URL)
if err != nil {
b.Fatal("Get:", err)
}
all, err := ioutil.ReadAll(res.Body)
if err != nil {
b.Fatal("ReadAll:", err)
}
if !bytes.Equal(all, msg) {
b.Fatalf("Got body %q; want %q", all, msg)
}
}
}
...@@ -7,12 +7,12 @@ ...@@ -7,12 +7,12 @@
package go1 package go1
import ( import (
"bytes"
"compress/bzip2" "compress/bzip2"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"io" "io"
"io/ioutil" "io/ioutil"
"strings"
"testing" "testing"
) )
...@@ -23,7 +23,7 @@ var ( ...@@ -23,7 +23,7 @@ var (
func makeJsonBytes() []byte { func makeJsonBytes() []byte {
var r io.Reader var r io.Reader
r = strings.NewReader(jsonbz2_base64) r = bytes.NewReader(bytes.Replace(jsonbz2_base64, []byte{'\n'}, nil, -1))
r = base64.NewDecoder(base64.StdEncoding, r) r = base64.NewDecoder(base64.StdEncoding, r)
r = bzip2.NewReader(r) r = bzip2.NewReader(r)
b, err := ioutil.ReadAll(r) b, err := ioutil.ReadAll(r)
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -33,7 +33,7 @@ func makeParserBytes() []byte { ...@@ -33,7 +33,7 @@ func makeParserBytes() []byte {
return b return b
} }
func BenchmarkParse(b *testing.B) { func BenchmarkGoParse(b *testing.B) {
b.SetBytes(int64(len(parserbytes))) b.SetBytes(int64(len(parserbytes)))
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
if _, err := parser.ParseFile(token.NewFileSet(), "", parserbytes, parser.ParseComments); err != nil { if _, err := parser.ParseFile(token.NewFileSet(), "", parserbytes, parser.ParseComments); err != nil {
......
// Copyright 2013 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 go1
import (
"math/rand"
"regexp"
"testing"
)
// benchmark based on regexp/exec_test.go
var regexpText []byte
func makeRegexpText(n int) []byte {
rand.Seed(0) // For reproducibility.
if len(regexpText) >= n {
return regexpText[:n]
}
regexpText = make([]byte, n)
for i := range regexpText {
if rand.Intn(30) == 0 {
regexpText[i] = '\n'
} else {
regexpText[i] = byte(rand.Intn(0x7E+1-0x20) + 0x20)
}
}
return regexpText
}
func benchmark(b *testing.B, re string, n int) {
r := regexp.MustCompile(re)
t := makeRegexpText(n)
b.ResetTimer()
b.SetBytes(int64(n))
for i := 0; i < b.N; i++ {
if r.Match(t) {
b.Fatal("match!")
}
}
}
const (
easy0 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ$"
easy1 = "A[AB]B[BC]C[CD]D[DE]E[EF]F[FG]G[GH]H[HI]I[IJ]J$"
medium = "[XYZ]ABCDEFGHIJKLMNOPQRSTUVWXYZ$"
hard = "[ -~]*ABCDEFGHIJKLMNOPQRSTUVWXYZ$"
)
func BenchmarkRegexpMatchEasy0_32(b *testing.B) { benchmark(b, easy0, 32<<0) }
func BenchmarkRegexpMatchEasy0_1K(b *testing.B) { benchmark(b, easy0, 1<<10) }
func BenchmarkRegexpMatchEasy1_32(b *testing.B) { benchmark(b, easy1, 32<<0) }
func BenchmarkRegexpMatchEasy1_1K(b *testing.B) { benchmark(b, easy1, 1<<10) }
func BenchmarkRegexpMatchMedium_32(b *testing.B) { benchmark(b, medium, 1<<0) }
func BenchmarkRegexpMatchMedium_1K(b *testing.B) { benchmark(b, medium, 1<<10) }
func BenchmarkRegexpMatchHard_32(b *testing.B) { benchmark(b, hard, 32<<0) }
func BenchmarkRegexpMatchHard_1K(b *testing.B) { benchmark(b, hard, 1<<10) }
// Copyright 2013 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 go1
// benchmark based on time/time_test.go
import (
"testing"
"time"
)
func BenchmarkTimeParse(b *testing.B) {
for i := 0; i < b.N; i++ {
time.Parse(time.ANSIC, "Mon Jan 2 15:04:05 2006")
}
}
func BenchmarkTimeFormat(b *testing.B) {
t := time.Unix(1265346057, 0)
for i := 0; i < b.N; i++ {
t.Format("Mon Jan 2 15:04:05 2006")
}
}
...@@ -10,6 +10,14 @@ O=$GOCHAR ...@@ -10,6 +10,14 @@ O=$GOCHAR
GC="go tool ${O}g" GC="go tool ${O}g"
LD="go tool ${O}l" LD="go tool ${O}l"
gccm=""
case "$O" in
8)
gccm=-m32;;
6)
gccm=-m64;;
esac
PATH=.:$PATH PATH=.:$PATH
havegccgo=false havegccgo=false
...@@ -78,7 +86,7 @@ run() { ...@@ -78,7 +86,7 @@ run() {
fasta() { fasta() {
runonly echo 'fasta -n 25000000' runonly echo 'fasta -n 25000000'
run 'gcc -O2 fasta.c' a.out 25000000 run "gcc $gccm -O2 fasta.c" a.out 25000000
run 'gccgo -O2 fasta.go' a.out -n 25000000 #commented out until WriteString is in bufio run 'gccgo -O2 fasta.go' a.out -n 25000000 #commented out until WriteString is in bufio
run 'gc fasta' $O.out -n 25000000 run 'gc fasta' $O.out -n 25000000
run 'gc_B fasta' $O.out -n 25000000 run 'gc_B fasta' $O.out -n 25000000
...@@ -88,7 +96,7 @@ revcomp() { ...@@ -88,7 +96,7 @@ revcomp() {
runonly gcc -O2 fasta.c runonly gcc -O2 fasta.c
runonly a.out 25000000 > x runonly a.out 25000000 > x
runonly echo 'reverse-complement < output-of-fasta-25000000' runonly echo 'reverse-complement < output-of-fasta-25000000'
run 'gcc -O2 reverse-complement.c' a.out < x run "gcc $gccm -O2 reverse-complement.c" a.out < x
run 'gccgo -O2 reverse-complement.go' a.out < x run 'gccgo -O2 reverse-complement.go' a.out < x
run 'gc reverse-complement' $O.out < x run 'gc reverse-complement' $O.out < x
run 'gc_B reverse-complement' $O.out < x run 'gc_B reverse-complement' $O.out < x
...@@ -97,7 +105,7 @@ revcomp() { ...@@ -97,7 +105,7 @@ revcomp() {
nbody() { nbody() {
runonly echo 'nbody -n 50000000' runonly echo 'nbody -n 50000000'
run 'gcc -O2 nbody.c -lm' a.out 50000000 run "gcc $gccm -O2 nbody.c -lm" a.out 50000000
run 'gccgo -O2 nbody.go' a.out -n 50000000 run 'gccgo -O2 nbody.go' a.out -n 50000000
run 'gc nbody' $O.out -n 50000000 run 'gc nbody' $O.out -n 50000000
run 'gc_B nbody' $O.out -n 50000000 run 'gc_B nbody' $O.out -n 50000000
...@@ -105,7 +113,7 @@ nbody() { ...@@ -105,7 +113,7 @@ nbody() {
binarytree() { binarytree() {
runonly echo 'binary-tree 15 # too slow to use 20' runonly echo 'binary-tree 15 # too slow to use 20'
run 'gcc -O2 binary-tree.c -lm' a.out 15 run "gcc $gccm -O2 binary-tree.c -lm" a.out 15
run 'gccgo -O2 binary-tree.go' a.out -n 15 run 'gccgo -O2 binary-tree.go' a.out -n 15
run 'gccgo -O2 binary-tree-freelist.go' a.out -n 15 run 'gccgo -O2 binary-tree-freelist.go' a.out -n 15
run 'gc binary-tree' $O.out -n 15 run 'gc binary-tree' $O.out -n 15
...@@ -114,7 +122,7 @@ binarytree() { ...@@ -114,7 +122,7 @@ binarytree() {
fannkuch() { fannkuch() {
runonly echo 'fannkuch 12' runonly echo 'fannkuch 12'
run 'gcc -O2 fannkuch.c' a.out 12 run "gcc $gccm -O2 fannkuch.c" a.out 12
run 'gccgo -O2 fannkuch.go' a.out -n 12 run 'gccgo -O2 fannkuch.go' a.out -n 12
run 'gccgo -O2 fannkuch-parallel.go' a.out -n 12 run 'gccgo -O2 fannkuch-parallel.go' a.out -n 12
run 'gc fannkuch' $O.out -n 12 run 'gc fannkuch' $O.out -n 12
...@@ -126,7 +134,7 @@ regexdna() { ...@@ -126,7 +134,7 @@ regexdna() {
runonly gcc -O2 fasta.c runonly gcc -O2 fasta.c
runonly a.out 100000 > x runonly a.out 100000 > x
runonly echo 'regex-dna 100000' runonly echo 'regex-dna 100000'
run 'gcc -O2 regex-dna.c -lpcre' a.out <x run "gcc $gccm -O2 regex-dna.c -lpcre" a.out <x
run 'gccgo -O2 regex-dna.go' a.out <x run 'gccgo -O2 regex-dna.go' a.out <x
run 'gccgo -O2 regex-dna-parallel.go' a.out <x run 'gccgo -O2 regex-dna-parallel.go' a.out <x
run 'gc regex-dna' $O.out <x run 'gc regex-dna' $O.out <x
...@@ -137,7 +145,7 @@ regexdna() { ...@@ -137,7 +145,7 @@ regexdna() {
spectralnorm() { spectralnorm() {
runonly echo 'spectral-norm 5500' runonly echo 'spectral-norm 5500'
run 'gcc -O2 spectral-norm.c -lm' a.out 5500 run "gcc $gccm -O2 spectral-norm.c -lm" a.out 5500
run 'gccgo -O2 spectral-norm.go' a.out -n 5500 run 'gccgo -O2 spectral-norm.go' a.out -n 5500
run 'gc spectral-norm' $O.out -n 5500 run 'gc spectral-norm' $O.out -n 5500
run 'gc_B spectral-norm' $O.out -n 5500 run 'gc_B spectral-norm' $O.out -n 5500
...@@ -160,7 +168,7 @@ knucleotide() { ...@@ -160,7 +168,7 @@ knucleotide() {
mandelbrot() { mandelbrot() {
runonly echo 'mandelbrot 16000' runonly echo 'mandelbrot 16000'
run 'gcc -O2 mandelbrot.c' a.out 16000 run "gcc $gccm -O2 mandelbrot.c" a.out 16000
run 'gccgo -O2 mandelbrot.go' a.out -n 16000 run 'gccgo -O2 mandelbrot.go' a.out -n 16000
run 'gc mandelbrot' $O.out -n 16000 run 'gc mandelbrot' $O.out -n 16000
run 'gc_B mandelbrot' $O.out -n 16000 run 'gc_B mandelbrot' $O.out -n 16000
...@@ -168,7 +176,7 @@ mandelbrot() { ...@@ -168,7 +176,7 @@ mandelbrot() {
meteor() { meteor() {
runonly echo 'meteor 2098' runonly echo 'meteor 2098'
run 'gcc -O2 meteor-contest.c' a.out 2098 run "gcc $gccm -O2 meteor-contest.c" a.out 2098
run 'gccgo -O2 meteor-contest.go' a.out -n 2098 run 'gccgo -O2 meteor-contest.go' a.out -n 2098
run 'gc meteor-contest' $O.out -n 2098 run 'gc meteor-contest' $O.out -n 2098
run 'gc_B meteor-contest' $O.out -n 2098 run 'gc_B meteor-contest' $O.out -n 2098
...@@ -176,7 +184,7 @@ meteor() { ...@@ -176,7 +184,7 @@ meteor() {
pidigits() { pidigits() {
runonly echo 'pidigits 10000' runonly echo 'pidigits 10000'
run 'gcc -O2 pidigits.c -lgmp' a.out 10000 run "gcc $gccm -O2 pidigits.c -lgmp" a.out 10000
run 'gccgo -O2 pidigits.go' a.out -n 10000 run 'gccgo -O2 pidigits.go' a.out -n 10000
run 'gc pidigits' $O.out -n 10000 run 'gc pidigits' $O.out -n 10000
run 'gc_B pidigits' $O.out -n 10000 run 'gc_B pidigits' $O.out -n 10000
...@@ -184,14 +192,14 @@ pidigits() { ...@@ -184,14 +192,14 @@ pidigits() {
threadring() { threadring() {
runonly echo 'threadring 50000000' runonly echo 'threadring 50000000'
run 'gcc -O2 threadring.c -lpthread' a.out 50000000 run "gcc $gccm -O2 threadring.c -lpthread" a.out 50000000
run 'gccgo -O2 threadring.go' a.out -n 50000000 run 'gccgo -O2 threadring.go' a.out -n 50000000
run 'gc threadring' $O.out -n 50000000 run 'gc threadring' $O.out -n 50000000
} }
chameneos() { chameneos() {
runonly echo 'chameneos 6000000' runonly echo 'chameneos 6000000'
run 'gcc -O2 chameneosredux.c -lpthread' a.out 6000000 run "gcc $gccm -O2 chameneosredux.c -lpthread" a.out 6000000
run 'gccgo -O2 chameneosredux.go' a.out 6000000 run 'gccgo -O2 chameneosredux.go' a.out 6000000
run 'gc chameneosredux' $O.out 6000000 run 'gc chameneosredux' $O.out 6000000
} }
......
...@@ -15,18 +15,21 @@ type T struct { ...@@ -15,18 +15,21 @@ type T struct {
d byte d byte
} }
var a = []int{ 1, 2, 3 } var a = []int{1, 2, 3}
var NIL []int var NIL []int
func arraycmptest() { func arraycmptest() {
if NIL != nil { if NIL != nil {
println("fail1:", NIL, "!= nil") println("fail1:", NIL, "!= nil")
panic("bigalg")
} }
if nil != NIL { if nil != NIL {
println("fail2: nil !=", NIL) println("fail2: nil !=", NIL)
panic("bigalg")
} }
if a == nil || nil == a { if a == nil || nil == a {
println("fail3:", a, "== nil") println("fail3:", a, "== nil")
panic("bigalg")
} }
} }
...@@ -49,12 +52,14 @@ func maptest() { ...@@ -49,12 +52,14 @@ func maptest() {
t1 := mt[0] t1 := mt[0]
if t1.a != t.a || t1.b != t.b || t1.c != t.c || t1.d != t.d { if t1.a != t.a || t1.b != t.b || t1.c != t.c || t1.d != t.d {
println("fail: map val struct", t1.a, t1.b, t1.c, t1.d) println("fail: map val struct", t1.a, t1.b, t1.c, t1.d)
panic("bigalg")
} }
ma[1] = a ma[1] = a
a1 := ma[1] a1 := ma[1]
if !SameArray(a, a1) { if !SameArray(a, a1) {
println("fail: map val array", a, a1) println("fail: map val array", a, a1)
panic("bigalg")
} }
} }
...@@ -72,15 +77,18 @@ func chantest() { ...@@ -72,15 +77,18 @@ func chantest() {
t1 := <-ct t1 := <-ct
if t1.a != t.a || t1.b != t.b || t1.c != t.c || t1.d != t.d { if t1.a != t.a || t1.b != t.b || t1.c != t.c || t1.d != t.d {
println("fail: map val struct", t1.a, t1.b, t1.c, t1.d) println("fail: map val struct", t1.a, t1.b, t1.c, t1.d)
panic("bigalg")
} }
a1 := <-ca a1 := <-ca
if !SameArray(a, a1) { if !SameArray(a, a1) {
println("fail: map val array", a, a1) println("fail: map val array", a, a1)
panic("bigalg")
} }
} }
type E struct { } type E struct{}
var e E var e E
func interfacetest() { func interfacetest() {
...@@ -90,6 +98,7 @@ func interfacetest() { ...@@ -90,6 +98,7 @@ func interfacetest() {
a1 := i.([]int) a1 := i.([]int)
if !SameArray(a, a1) { if !SameArray(a, a1) {
println("interface <-> []int", a, a1) println("interface <-> []int", a, a1)
panic("bigalg")
} }
pa := new([]int) pa := new([]int)
*pa = a *pa = a
...@@ -97,12 +106,14 @@ func interfacetest() { ...@@ -97,12 +106,14 @@ func interfacetest() {
a1 = *i.(*[]int) a1 = *i.(*[]int)
if !SameArray(a, a1) { if !SameArray(a, a1) {
println("interface <-> *[]int", a, a1) println("interface <-> *[]int", a, a1)
panic("bigalg")
} }
i = t i = t
t1 := i.(T) t1 := i.(T)
if t1.a != t.a || t1.b != t.b || t1.c != t.c || t1.d != t.d { if t1.a != t.a || t1.b != t.b || t1.c != t.c || t1.d != t.d {
println("interface <-> struct", t1.a, t1.b, t1.c, t1.d) println("interface <-> struct", t1.a, t1.b, t1.c, t1.d)
panic("bigalg")
} }
i = e i = e
......
...@@ -8,6 +8,11 @@ ...@@ -8,6 +8,11 @@
package main package main
import (
"os"
"unsafe"
)
import _ "fmt" import _ "fmt"
var call string var call string
...@@ -102,8 +107,19 @@ func main() { ...@@ -102,8 +107,19 @@ func main() {
panic(sum) panic(sum)
} }
// exp/ssa/interp doesn't yet skip blank fields in struct
// equivalence. It also cannot support unsafe.Pointer.
if os.Getenv("GOSSAINTERP") == "" {
type T1 struct{ x, y, z int }
t1 := *(*T)(unsafe.Pointer(&T1{1, 2, 3}))
t2 := *(*T)(unsafe.Pointer(&T1{4, 5, 6}))
if t1 != t2 {
panic("T{} != T{}")
}
}
h(a, b) h(a, b)
m() m()
} }
...@@ -133,14 +149,13 @@ func fp1(x, y int) { ...@@ -133,14 +149,13 @@ func fp1(x, y int) {
} }
} }
func m() { func m() {
var i I var i I
i = TI{} i = TI{}
i.M(1, 1) i.M(1, 1)
i.M(2, 2) i.M(2, 2)
fp(1, 1) fp(1, 1)
fp(2, 2) fp(2, 2)
} }
...@@ -162,4 +177,3 @@ func _() { ...@@ -162,4 +177,3 @@ func _() {
func ff() { func ff() {
var _ int = 1 var _ int = 1
} }
...@@ -9,8 +9,13 @@ ...@@ -9,8 +9,13 @@
package _ // ERROR "invalid package name _" package _ // ERROR "invalid package name _"
var t struct {
_ int
}
func main() { func main() {
_() // ERROR "cannot use _ as value" _() // ERROR "cannot use _ as value"
x := _+1 // ERROR "cannot use _ as value" x := _+1 // ERROR "cannot use _ as value"
_ = x _ = x
_ = t._ // ERROR "cannot refer to blank field|invalid use of"
} }
...@@ -47,7 +47,7 @@ func main() { ...@@ -47,7 +47,7 @@ func main() {
runtime.GC() runtime.GC()
runtime.ReadMemStats(memstats) runtime.ReadMemStats(memstats)
if memstats.Alloc-alloc > 1e5 { if memstats.Alloc-alloc > 1.1e5 {
println("BUG: too much memory for 100,000 selects:", memstats.Alloc-alloc) println("BUG: too much memory for 100,000 selects:", memstats.Alloc-alloc)
} }
} }
...@@ -8,9 +8,13 @@ ...@@ -8,9 +8,13 @@
package main package main
import "unsafe" import (
"os"
"unsafe"
)
var global bool var global bool
func use(b bool) { global = b } func use(b bool) { global = b }
func stringptr(s string) uintptr { return *(*uintptr)(unsafe.Pointer(&s)) } func stringptr(s string) uintptr { return *(*uintptr)(unsafe.Pointer(&s)) }
...@@ -38,8 +42,12 @@ func main() { ...@@ -38,8 +42,12 @@ func main() {
var c string = "hello" var c string = "hello"
var d string = "hel" // try to get different pointer var d string = "hel" // try to get different pointer
d = d + "lo" d = d + "lo"
if stringptr(c) == stringptr(d) {
panic("compiler too smart -- got same string") // exp/ssa/interp can't handle unsafe.Pointer.
if os.Getenv("GOSSAINTERP") != "" {
if stringptr(c) == stringptr(d) {
panic("compiler too smart -- got same string")
}
} }
var e = make(chan int) var e = make(chan int)
...@@ -283,7 +291,7 @@ func main() { ...@@ -283,7 +291,7 @@ func main() {
isfalse(ix != z) isfalse(ix != z)
isfalse(iz != x) isfalse(iz != x)
} }
// structs with _ fields // structs with _ fields
{ {
var x = struct { var x = struct {
...@@ -296,7 +304,7 @@ func main() { ...@@ -296,7 +304,7 @@ func main() {
x: 1, y: 2, z: 3, x: 1, y: 2, z: 3,
} }
var ix interface{} = x var ix interface{} = x
istrue(x == x) istrue(x == x)
istrue(x == ix) istrue(x == ix)
istrue(ix == x) istrue(ix == x)
......
...@@ -9,12 +9,23 @@ ...@@ -9,12 +9,23 @@
package main package main
type (
Float32 float32
Float64 float64
Complex64 complex64
Complex128 complex128
)
var ( var (
f32 float32 f32 float32
f64 float64 f64 float64
F32 Float32
F64 Float64
c64 complex64 c64 complex64
c128 complex128 c128 complex128
C64 Complex64
C128 Complex128
) )
func main() { func main() {
...@@ -25,4 +36,19 @@ func main() { ...@@ -25,4 +36,19 @@ func main() {
_ = complex128(0) // ok _ = complex128(0) // ok
_ = complex(f32, f64) // ERROR "complex" _ = complex(f32, f64) // ERROR "complex"
_ = complex(f64, f32) // ERROR "complex" _ = complex(f64, f32) // ERROR "complex"
_ = complex(f32, F32) // ERROR "complex"
_ = complex(F32, f32) // ERROR "complex"
_ = complex(f64, F64) // ERROR "complex"
_ = complex(F64, f64) // ERROR "complex"
c128 = complex(f32, f32) // ERROR "cannot use"
c64 = complex(f64, f64) // ERROR "cannot use"
c64 = complex(1.0, 2.0) // ok, constant is untyped
c128 = complex(1.0, 2.0)
C64 = complex(1.0, 2.0)
C128 = complex(1.0, 2.0)
C64 = complex(f32, f32) // ERROR "cannot use"
C128 = complex(f64, f64) // ERROR "cannot use"
} }
...@@ -45,4 +45,7 @@ func main() { ...@@ -45,4 +45,7 @@ func main() {
fmt.Printf("%v/%v: expected %v error; got %v\n", t.f, t.g, t.out, x) fmt.Printf("%v/%v: expected %v error; got %v\n", t.f, t.g, t.out, x)
} }
} }
if bad {
panic("cmplxdivide failed.")
}
} }
...@@ -8,27 +8,29 @@ ...@@ -8,27 +8,29 @@
package main package main
import "os"
const ( const (
c0 = 0 c0 = 0
cm1 = -1 cm1 = -1
chuge = 1 << 100 chuge = 1 << 100
chuge_1 = chuge - 1 chuge_1 = chuge - 1
c1 = chuge >> 100 c1 = chuge >> 100
c3div2 = 3/2 c3div2 = 3 / 2
c1e3 = 1e3 c1e3 = 1e3
ctrue = true ctrue = true
cfalse = !ctrue cfalse = !ctrue
) )
const ( const (
f0 = 0.0 f0 = 0.0
fm1 = -1. fm1 = -1.
fhuge float64 = 1 << 100 fhuge float64 = 1 << 100
fhuge_1 float64 = chuge - 1 fhuge_1 float64 = chuge - 1
f1 float64 = chuge >> 100 f1 float64 = chuge >> 100
f3div2 = 3./2. f3div2 = 3. / 2.
f1e3 float64 = 1e3 f1e3 float64 = 1e3
) )
func assert(t bool, s string) { func assert(t bool, s string) {
...@@ -41,8 +43,8 @@ func ints() { ...@@ -41,8 +43,8 @@ func ints() {
assert(c0 == 0, "c0") assert(c0 == 0, "c0")
assert(c1 == 1, "c1") assert(c1 == 1, "c1")
assert(chuge > chuge_1, "chuge") assert(chuge > chuge_1, "chuge")
assert(chuge_1 + 1 == chuge, "chuge 1") assert(chuge_1+1 == chuge, "chuge 1")
assert(chuge + cm1 +1 == chuge, "cm1") assert(chuge+cm1+1 == chuge, "cm1")
assert(c3div2 == 1, "3/2") assert(c3div2 == 1, "3/2")
assert(c1e3 == 1000, "c1e3 int") assert(c1e3 == 1000, "c1e3 int")
assert(c1e3 == 1e3, "c1e3 float") assert(c1e3 == 1e3, "c1e3 float")
...@@ -81,9 +83,12 @@ func ints() { ...@@ -81,9 +83,12 @@ func ints() {
func floats() { func floats() {
assert(f0 == c0, "f0") assert(f0 == c0, "f0")
assert(f1 == c1, "f1") assert(f1 == c1, "f1")
assert(fhuge == fhuge_1, "fhuge") // float64 can't distinguish fhuge, fhuge_1. // TODO(gri): exp/ssa/interp constant folding is incorrect.
assert(fhuge_1 + 1 == fhuge, "fhuge 1") if os.Getenv("GOSSAINTERP") == "" {
assert(fhuge + fm1 +1 == fhuge, "fm1") assert(fhuge == fhuge_1, "fhuge") // float64 can't distinguish fhuge, fhuge_1.
}
assert(fhuge_1+1 == fhuge, "fhuge 1")
assert(fhuge+fm1+1 == fhuge, "fm1")
assert(f3div2 == 1.5, "3./2.") assert(f3div2 == 1.5, "3./2.")
assert(f1e3 == 1000, "f1e3 int") assert(f1e3 == 1000, "f1e3 int")
assert(f1e3 == 1.e3, "f1e3 float") assert(f1e3 == 1.e3, "f1e3 float")
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
package main package main
import "unsafe"
type I interface{} type I interface{}
const ( const (
...@@ -86,3 +88,7 @@ func main() { ...@@ -86,3 +88,7 @@ func main() {
} }
const ptr = nil // ERROR "const.*nil" const ptr = nil // ERROR "const.*nil"
const _ = string([]byte(nil)) // ERROR "is not a? ?constant"
const _ = uintptr(unsafe.Pointer((*int)(nil))) // ERROR "is not a? ?constant"
const _ = unsafe.Pointer((*int)(nil)) // ERROR "cannot be nil|invalid constant type"
const _ = (*int)(nil) // ERROR "cannot be nil|invalid constant type"
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
package main package main
var b struct { var b struct {
a[10]int a [10]int
} }
var m map[string][20]int var m map[string][20]int
...@@ -61,17 +61,22 @@ var c1 = func() chan *[70]int { ...@@ -61,17 +61,22 @@ var c1 = func() chan *[70]int {
func main() { func main() {
if n1 != 10 || n2 != 20 || n3 != 30 || n4 != 40 || n5 != 50 || n6 != 60 || n7 != 70 { if n1 != 10 || n2 != 20 || n3 != 30 || n4 != 40 || n5 != 50 || n6 != 60 || n7 != 70 {
println("BUG:", n1, n2, n3, n4, n5, n6, n7) println("BUG:", n1, n2, n3, n4, n5, n6, n7)
panic("fail")
} }
if !calledF { if !calledF {
println("BUG: did not call f") println("BUG: did not call f")
panic("fail")
} }
if <-c == nil { if <-c == nil {
println("BUG: did not receive from c") println("BUG: did not receive from c")
panic("fail")
} }
if !calledG { if !calledG {
println("BUG: did not call g") println("BUG: did not call g")
panic("fail")
} }
if <-c1 == nil { if <-c1 == nil {
println("BUG: did not receive from c1") println("BUG: did not receive from c1")
panic("fail")
} }
} }
...@@ -24,10 +24,10 @@ const ( ...@@ -24,10 +24,10 @@ const (
n2 = len(m[""]) n2 = len(m[""])
n3 = len(s[10]) n3 = len(s[10])
n4 = len(f()) // ERROR "must be constant|is not constant" n4 = len(f()) // ERROR "is not a constant|is not constant"
n5 = len(<-c) // ERROR "must be constant|is not constant" n5 = len(<-c) // ERROR "is not a constant|is not constant"
n6 = cap(f()) // ERROR "must be constant|is not constant" n6 = cap(f()) // ERROR "is not a constant|is not constant"
n7 = cap(<-c) // ERROR "must be constant|is not constant" n7 = cap(<-c) // ERROR "is not a constant|is not constant"
) )
// errorcheck
// Copyright 2013 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.
// Ideal vs non-ideal bool. See issue 3915, 3923.
package p
type mybool bool
type mybool1 bool
var (
x, y int = 1, 2
c1 bool = x < y
c2 mybool = x < y
c3 mybool = c2 == (x < y)
c4 mybool = c2 == (1 < 2)
c5 mybool = 1 < 2
c6 mybool1 = x < y
c7 = c1 == c2 // ERROR "mismatched types|incompatible types"
c8 = c2 == c6 // ERROR "mismatched types|incompatible types"
c9 = c1 == c6 // ERROR "mismatched types|incompatible types"
_ = c2 && (x < y)
_ = c2 && (1 < 2)
_ = c1 && c2 // ERROR "mismatched types|incompatible types"
_ = c2 && c6 // ERROR "mismatched types|incompatible types"
_ = c1 && c6 // ERROR "mismatched types|incompatible types"
)
...@@ -132,6 +132,7 @@ func verify8(length, in, out, m int) { ...@@ -132,6 +132,7 @@ func verify8(length, in, out, m int) {
n := ncopied(length, in, out) n := ncopied(length, in, out)
if m != n { if m != n {
fmt.Printf("count bad(%d %d %d): %d not %d\n", length, in, out, m, n) fmt.Printf("count bad(%d %d %d): %d not %d\n", length, in, out, m, n)
os.Exit(1)
return return
} }
// before // before
...@@ -172,6 +173,7 @@ func verifyS(length, in, out, m int) { ...@@ -172,6 +173,7 @@ func verifyS(length, in, out, m int) {
n := ncopied(length, in, out) n := ncopied(length, in, out)
if m != n { if m != n {
fmt.Printf("count bad(%d %d %d): %d not %d\n", length, in, out, m, n) fmt.Printf("count bad(%d %d %d): %d not %d\n", length, in, out, m, n)
os.Exit(1)
return return
} }
// before // before
...@@ -212,6 +214,7 @@ func verify16(length, in, out, m int) { ...@@ -212,6 +214,7 @@ func verify16(length, in, out, m int) {
n := ncopied(length, in, out) n := ncopied(length, in, out)
if m != n { if m != n {
fmt.Printf("count bad(%d %d %d): %d not %d\n", length, in, out, m, n) fmt.Printf("count bad(%d %d %d): %d not %d\n", length, in, out, m, n)
os.Exit(1)
return return
} }
// before // before
...@@ -252,6 +255,7 @@ func verify32(length, in, out, m int) { ...@@ -252,6 +255,7 @@ func verify32(length, in, out, m int) {
n := ncopied(length, in, out) n := ncopied(length, in, out)
if m != n { if m != n {
fmt.Printf("count bad(%d %d %d): %d not %d\n", length, in, out, m, n) fmt.Printf("count bad(%d %d %d): %d not %d\n", length, in, out, m, n)
os.Exit(1)
return return
} }
// before // before
...@@ -292,6 +296,7 @@ func verify64(length, in, out, m int) { ...@@ -292,6 +296,7 @@ func verify64(length, in, out, m int) {
n := ncopied(length, in, out) n := ncopied(length, in, out)
if m != n { if m != n {
fmt.Printf("count bad(%d %d %d): %d not %d\n", length, in, out, m, n) fmt.Printf("count bad(%d %d %d): %d not %d\n", length, in, out, m, n)
os.Exit(1)
return return
} }
// before // before
......
// Copyright 2010 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.
// This file is compiled and then imported by ddd3.go.
package ddd
func Sum(args ...int) int {
s := 0
for _, v := range args {
s += v
}
return s
}
// $G $D/ddd2.go && $G $D/$F.go && $L $F.$A && ./$A.out
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2010 The Go Authors. All rights reserved. // Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
......
// skip // rundir
// Copyright 2010 The Go Authors. All rights reserved. // Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// This file is compiled and then imported by ddd3.go. // Test that variadic functions work across package boundaries.
package ddd
func Sum(args ...int) int {
s := 0
for _, v := range args {
s += v
}
return s
}
package ignored
...@@ -33,8 +33,9 @@ func main() { ...@@ -33,8 +33,9 @@ func main() {
m, h, s := f3() m, h, s := f3()
_, _, _, _, _, _, _, _, _ = i, f, s, j, k, m, g, s, h _, _, _, _, _, _, _, _, _ = i, f, s, j, k, m, g, s, h
} }
if x() != "3" { if y := x(); y != "3" {
println("x() failed") println("x() failed", y)
panic("fail")
} }
_, _, _, _, _, _, _, _, _ = i, f, s, j, k, m, g, s, h _, _, _, _, _, _, _, _, _ = i, f, s, j, k, m, g, s, h
} }
...@@ -41,7 +41,8 @@ func main() { ...@@ -41,7 +41,8 @@ func main() {
{ {
// multiline no new variables // multiline no new variables
i := f1 i := f1
i := func() { // ERROR "redeclared|no new|incompatible" i := func() int { // ERROR "redeclared|no new|incompatible"
return 0
} }
_ = i _ = i
} }
......
...@@ -25,6 +25,7 @@ func test1() { ...@@ -25,6 +25,7 @@ func test1() {
test1helper() test1helper()
if result != "9876543210" { if result != "9876543210" {
fmt.Printf("test1: bad defer result (should be 9876543210): %q\n", result) fmt.Printf("test1: bad defer result (should be 9876543210): %q\n", result)
panic("defer")
} }
} }
...@@ -41,6 +42,7 @@ func test2() { ...@@ -41,6 +42,7 @@ func test2() {
test2helper() test2helper()
if result != "9876543210" { if result != "9876543210" {
fmt.Printf("test2: bad defer result (should be 9876543210): %q\n", result) fmt.Printf("test2: bad defer result (should be 9876543210): %q\n", result)
panic("defer")
} }
} }
......
...@@ -13,36 +13,44 @@ import "fmt" ...@@ -13,36 +13,44 @@ import "fmt"
func f8(x, y, q, r int8) { func f8(x, y, q, r int8) {
if t := x / y; t != q { if t := x / y; t != q {
fmt.Printf("%d/%d = %d, want %d\n", x, y, t, q) fmt.Printf("%d/%d = %d, want %d\n", x, y, t, q)
panic("divide")
} }
if t := x % y; t != r { if t := x % y; t != r {
fmt.Printf("%d%%%d = %d, want %d\n", x, y, t, r) fmt.Printf("%d%%%d = %d, want %d\n", x, y, t, r)
panic("divide")
} }
} }
func f16(x, y, q, r int16) { func f16(x, y, q, r int16) {
if t := x / y; t != q { if t := x / y; t != q {
fmt.Printf("%d/%d = %d, want %d\n", x, y, t, q) fmt.Printf("%d/%d = %d, want %d\n", x, y, t, q)
panic("divide")
} }
if t := x % y; t != r { if t := x % y; t != r {
fmt.Printf("%d%%%d = %d, want %d\n", x, y, t, r) fmt.Printf("%d%%%d = %d, want %d\n", x, y, t, r)
panic("divide")
} }
} }
func f32(x, y, q, r int32) { func f32(x, y, q, r int32) {
if t := x / y; t != q { if t := x / y; t != q {
fmt.Printf("%d/%d = %d, want %d\n", x, y, t, q) fmt.Printf("%d/%d = %d, want %d\n", x, y, t, q)
panic("divide")
} }
if t := x % y; t != r { if t := x % y; t != r {
fmt.Printf("%d%%%d = %d, want %d\n", x, y, t, r) fmt.Printf("%d%%%d = %d, want %d\n", x, y, t, r)
panic("divide")
} }
} }
func f64(x, y, q, r int64) { func f64(x, y, q, r int64) {
if t := x / y; t != q { if t := x / y; t != q {
fmt.Printf("%d/%d = %d, want %d\n", x, y, t, q) fmt.Printf("%d/%d = %d, want %d\n", x, y, t, q)
panic("divide")
} }
if t := x % y; t != r { if t := x % y; t != r {
fmt.Printf("%d%%%d = %d, want %d\n", x, y, t, r) fmt.Printf("%d%%%d = %d, want %d\n", x, y, t, r)
panic("divide")
} }
} }
......
// rundir
// Copyright 2009 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.
// See issue 2241 and issue 1878: dwarf include stack size
// issues in linker.
package ignored
...@@ -31,7 +31,7 @@ if(@ARGV < 1) { ...@@ -31,7 +31,7 @@ if(@ARGV < 1) {
# Grab SOURCEFILES # Grab SOURCEFILES
foreach(reverse 0 .. @ARGV-1) { foreach(reverse 0 .. @ARGV-1) {
unless($ARGV[$_] =~ /\.go$/) { unless($ARGV[$_] =~ /\.(go|s)$/) {
@file = @ARGV[$_+1 .. @ARGV-1]; @file = @ARGV[$_+1 .. @ARGV-1];
last; last;
} }
......
...@@ -52,9 +52,11 @@ func chk(p, q *int, v int, s string) { ...@@ -52,9 +52,11 @@ func chk(p, q *int, v int, s string) {
func chkalias(p, q *int, v int, s string) { func chkalias(p, q *int, v int, s string) {
if p != q { if p != q {
println("want aliased pointers but got different after", s) println("want aliased pointers but got different after", s)
bad = true
} }
if *q != v+1 { if *q != v+1 {
println("wrong value want", v+1, "got", *q, "after", s) println("wrong value want", v+1, "got", *q, "after", s)
bad = true
} }
} }
......
...@@ -80,7 +80,9 @@ func foo12(yyy **int) { // ERROR "leaking param: yyy" ...@@ -80,7 +80,9 @@ func foo12(yyy **int) { // ERROR "leaking param: yyy"
xxx = yyy xxx = yyy
} }
func foo13(yyy **int) { // ERROR "yyy does not escape" // Must treat yyy as leaking because *yyy leaks, and the escape analysis
// summaries in exported metadata do not distinguish these two cases.
func foo13(yyy **int) { // ERROR "leaking param: yyy"
*xxx = *yyy *xxx = *yyy
} }
...@@ -142,13 +144,13 @@ func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b" ...@@ -142,13 +144,13 @@ func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b"
} }
func (b Bar) LeaksToo() *int { // ERROR "leaking param: b" func (b Bar) LeaksToo() *int { // ERROR "leaking param: b"
v := 0 // ERROR "moved to heap: v" v := 0 // ERROR "moved to heap: v"
b.ii = &v // ERROR "&v escapes" b.ii = &v // ERROR "&v escapes"
return b.ii return b.ii
} }
func (b *Bar) LeaksABit() *int { // ERROR "b does not escape" func (b *Bar) LeaksABit() *int { // ERROR "b does not escape"
v := 0 // ERROR "moved to heap: v" v := 0 // ERROR "moved to heap: v"
b.ii = &v // ERROR "&v escapes" b.ii = &v // ERROR "&v escapes"
return b.ii return b.ii
} }
...@@ -299,7 +301,8 @@ func (f *Foo) foo45() { // ERROR "f does not escape" ...@@ -299,7 +301,8 @@ func (f *Foo) foo45() { // ERROR "f does not escape"
F.x = f.x F.x = f.x
} }
func (f *Foo) foo46() { // ERROR "f does not escape" // See foo13 above for explanation of why f leaks.
func (f *Foo) foo46() { // ERROR "leaking param: f"
F.xx = f.xx F.xx = f.xx
} }
...@@ -561,12 +564,21 @@ func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "y does not esca ...@@ -561,12 +564,21 @@ func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "y does not esca
return &x[0] // ERROR "&x.0. escapes to heap" return &x[0] // ERROR "&x.0. escapes to heap"
} }
func foo75(z *int) { // ERROR "leaking param: z" func foo75(z *int) { // ERROR "z does not escape"
myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape" myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
} }
func foo75a(z *int) { // ERROR "z does not escape" func foo75a(z *int) { // ERROR "z does not escape"
myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap" myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
}
func foo75esc(z *int) { // ERROR "leaking param: z"
gxx = myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
}
func foo75aesc(z *int) { // ERROR "z does not escape"
var ppi **interface{} // assignments to pointer dereferences lose track
*ppi = myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
} }
func foo76(z *int) { // ERROR "leaking param: z" func foo76(z *int) { // ERROR "leaking param: z"
...@@ -574,7 +586,7 @@ func foo76(z *int) { // ERROR "leaking param: z" ...@@ -574,7 +586,7 @@ func foo76(z *int) { // ERROR "leaking param: z"
} }
func foo76a(z *int) { // ERROR "leaking param: z" func foo76a(z *int) { // ERROR "leaking param: z"
myprint1(nil, z) // ERROR "[.][.][.] argument escapes to heap" myprint1(nil, z) // ERROR "[.][.][.] argument does not escape"
} }
func foo76b() { func foo76b() {
...@@ -582,7 +594,7 @@ func foo76b() { ...@@ -582,7 +594,7 @@ func foo76b() {
} }
func foo76c() { func foo76c() {
myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap" myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
} }
func foo76d() { func foo76d() {
...@@ -590,7 +602,7 @@ func foo76d() { ...@@ -590,7 +602,7 @@ func foo76d() {
} }
func foo76e() { func foo76e() {
defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap" defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
} }
func foo76f() { func foo76f() {
...@@ -610,10 +622,15 @@ func foo77(z []interface{}) { // ERROR "z does not escape" ...@@ -610,10 +622,15 @@ func foo77(z []interface{}) { // ERROR "z does not escape"
myprint(nil, z...) // z does not escape myprint(nil, z...) // z does not escape
} }
func foo77a(z []interface{}) { // ERROR "leaking param: z" func foo77a(z []interface{}) { // ERROR "z does not escape"
myprint1(nil, z...) myprint1(nil, z...)
} }
func foo77b(z []interface{}) { // ERROR "leaking param: z"
var ppi **interface{}
*ppi = myprint1(nil, z...)
}
func foo78(z int) *int { // ERROR "moved to heap: z" func foo78(z int) *int { // ERROR "moved to heap: z"
return &z // ERROR "&z escapes to heap" return &z // ERROR "&z escapes to heap"
} }
...@@ -646,6 +663,21 @@ func foo81() *int { ...@@ -646,6 +663,21 @@ func foo81() *int {
return nil return nil
} }
func tee(p *int) (x, y *int) { return p, p } // ERROR "leaking param"
func noop(x, y *int) {} // ERROR "does not escape"
func foo82() {
var x, y, z int // ERROR "moved to heap"
go noop(tee(&z)) // ERROR "&z escapes to heap"
go noop(&x, &y) // ERROR "escapes to heap"
for {
var u, v, w int // ERROR "moved to heap"
defer noop(tee(&u)) // ERROR "&u escapes to heap"
defer noop(&v, &w) // ERROR "escapes to heap"
}
}
type Fooer interface { type Fooer interface {
Foo() Foo()
} }
...@@ -1079,29 +1111,29 @@ L1: ...@@ -1079,29 +1111,29 @@ L1:
_ = i _ = i
} }
func foo124(x **int) { // ERROR "x does not escape" func foo124(x **int) { // ERROR "x does not escape"
var i int // ERROR "moved to heap: i" var i int // ERROR "moved to heap: i"
p := &i // ERROR "&i escapes" p := &i // ERROR "&i escapes"
func() { // ERROR "func literal does not escape" func() { // ERROR "func literal does not escape"
*x = p // ERROR "leaking closure reference p" *x = p // ERROR "leaking closure reference p"
}() }()
} }
func foo125(ch chan *int) { // ERROR "does not escape" func foo125(ch chan *int) { // ERROR "does not escape"
var i int // ERROR "moved to heap" var i int // ERROR "moved to heap"
p := &i // ERROR "&i escapes to heap" p := &i // ERROR "&i escapes to heap"
func() { // ERROR "func literal does not escape" func() { // ERROR "func literal does not escape"
ch <- p // ERROR "leaking closure reference p" ch <- p // ERROR "leaking closure reference p"
}() }()
} }
func foo126() { func foo126() {
var px *int // loopdepth 0 var px *int // loopdepth 0
for { for {
// loopdepth 1 // loopdepth 1
var i int // ERROR "moved to heap" var i int // ERROR "moved to heap"
func() { // ERROR "func literal does not escape" func() { // ERROR "func literal does not escape"
px = &i // ERROR "&i escapes" px = &i // ERROR "&i escapes"
}() }()
} }
} }
...@@ -1109,8 +1141,8 @@ func foo126() { ...@@ -1109,8 +1141,8 @@ func foo126() {
var px *int var px *int
func foo127() { func foo127() {
var i int // ERROR "moved to heap: i" var i int // ERROR "moved to heap: i"
p := &i // ERROR "&i escapes to heap" p := &i // ERROR "&i escapes to heap"
q := p q := p
px = q px = q
} }
...@@ -1123,12 +1155,12 @@ func foo128() { ...@@ -1123,12 +1155,12 @@ func foo128() {
} }
func foo129() { func foo129() {
var i int // ERROR "moved to heap: i" var i int // ERROR "moved to heap: i"
p := &i // ERROR "&i escapes to heap" p := &i // ERROR "&i escapes to heap"
func() { // ERROR "func literal does not escape" func() { // ERROR "func literal does not escape"
q := p // ERROR "leaking closure reference p" q := p // ERROR "leaking closure reference p"
func() { // ERROR "func literal does not escape" func() { // ERROR "func literal does not escape"
r := q // ERROR "leaking closure reference q" r := q // ERROR "leaking closure reference q"
px = r px = r
}() }()
}() }()
...@@ -1136,40 +1168,40 @@ func foo129() { ...@@ -1136,40 +1168,40 @@ func foo129() {
func foo130() { func foo130() {
for { for {
var i int // ERROR "moved to heap" var i int // ERROR "moved to heap"
func() { // ERROR "func literal does not escape" func() { // ERROR "func literal does not escape"
px = &i // ERROR "&i escapes" "leaking closure reference i" px = &i // ERROR "&i escapes" "leaking closure reference i"
}() }()
} }
} }
func foo131() { func foo131() {
var i int // ERROR "moved to heap" var i int // ERROR "moved to heap"
func() { // ERROR "func literal does not escape" func() { // ERROR "func literal does not escape"
px = &i // ERROR "&i escapes" "leaking closure reference i" px = &i // ERROR "&i escapes" "leaking closure reference i"
}() }()
} }
func foo132() { func foo132() {
var i int // ERROR "moved to heap" var i int // ERROR "moved to heap"
go func() { // ERROR "func literal escapes to heap" go func() { // ERROR "func literal escapes to heap"
px = &i // ERROR "&i escapes" "leaking closure reference i" px = &i // ERROR "&i escapes" "leaking closure reference i"
}() }()
} }
func foo133() { func foo133() {
var i int // ERROR "moved to heap" var i int // ERROR "moved to heap"
defer func() { // ERROR "func literal does not escape" defer func() { // ERROR "func literal does not escape"
px = &i // ERROR "&i escapes" "leaking closure reference i" px = &i // ERROR "&i escapes" "leaking closure reference i"
}() }()
} }
func foo134() { func foo134() {
var i int var i int
p := &i // ERROR "&i does not escape" p := &i // ERROR "&i does not escape"
func() { // ERROR "func literal does not escape" func() { // ERROR "func literal does not escape"
q := p q := p
func() { // ERROR "func literal does not escape" func() { // ERROR "func literal does not escape"
r := q r := q
_ = r _ = r
}() }()
...@@ -1177,11 +1209,11 @@ func foo134() { ...@@ -1177,11 +1209,11 @@ func foo134() {
} }
func foo135() { func foo135() {
var i int // ERROR "moved to heap: i" var i int // ERROR "moved to heap: i"
p := &i // ERROR "&i escapes to heap" "moved to heap: p" p := &i // ERROR "&i escapes to heap" "moved to heap: p"
go func() { // ERROR "func literal escapes to heap" go func() { // ERROR "func literal escapes to heap"
q := p // ERROR "&p escapes to heap" q := p // ERROR "&p escapes to heap"
func() { // ERROR "func literal does not escape" func() { // ERROR "func literal does not escape"
r := q r := q
_ = r _ = r
}() }()
...@@ -1189,11 +1221,11 @@ func foo135() { ...@@ -1189,11 +1221,11 @@ func foo135() {
} }
func foo136() { func foo136() {
var i int // ERROR "moved to heap: i" var i int // ERROR "moved to heap: i"
p := &i // ERROR "&i escapes to heap" "moved to heap: p" p := &i // ERROR "&i escapes to heap" "moved to heap: p"
go func() { // ERROR "func literal escapes to heap" go func() { // ERROR "func literal escapes to heap"
q := p // ERROR "&p escapes to heap" "leaking closure reference p" q := p // ERROR "&p escapes to heap" "leaking closure reference p"
func() { // ERROR "func literal does not escape" func() { // ERROR "func literal does not escape"
r := q // ERROR "leaking closure reference q" r := q // ERROR "leaking closure reference q"
px = r px = r
}() }()
...@@ -1201,12 +1233,12 @@ func foo136() { ...@@ -1201,12 +1233,12 @@ func foo136() {
} }
func foo137() { func foo137() {
var i int // ERROR "moved to heap: i" var i int // ERROR "moved to heap: i"
p := &i // ERROR "&i escapes to heap" p := &i // ERROR "&i escapes to heap"
func() { // ERROR "func literal does not escape" func() { // ERROR "func literal does not escape"
q := p // ERROR "leaking closure reference p" "moved to heap: q" q := p // ERROR "leaking closure reference p" "moved to heap: q"
go func() { // ERROR "func literal escapes to heap" go func() { // ERROR "func literal escapes to heap"
r := q // ERROR "&q escapes to heap" r := q // ERROR "&q escapes to heap"
_ = r _ = r
}() }()
}() }()
...@@ -1216,7 +1248,7 @@ func foo138() *byte { ...@@ -1216,7 +1248,7 @@ func foo138() *byte {
type T struct { type T struct {
x [1]byte x [1]byte
} }
t := new(T) // ERROR "new.T. escapes to heap" t := new(T) // ERROR "new.T. escapes to heap"
return &t.x[0] // ERROR "&t.x.0. escapes to heap" return &t.x[0] // ERROR "&t.x.0. escapes to heap"
} }
...@@ -1226,6 +1258,70 @@ func foo139() *byte { ...@@ -1226,6 +1258,70 @@ func foo139() *byte {
y byte y byte
} }
} }
t := new(T) // ERROR "new.T. escapes to heap" t := new(T) // ERROR "new.T. escapes to heap"
return &t.x.y // ERROR "&t.x.y escapes to heap" return &t.x.y // ERROR "&t.x.y escapes to heap"
} }
// issue 4751
func foo140() interface{} {
type T struct {
X string
}
type U struct {
X string
T *T
}
t := &T{} // ERROR "&T literal escapes to heap"
return U{
X: t.X,
T: t,
}
}
//go:noescape
func F1([]byte)
func F2([]byte)
//go:noescape
func F3(x []byte) // ERROR "F3 x does not escape"
func F4(x []byte)
func G() {
var buf1 [10]byte
F1(buf1[:]) // ERROR "buf1 does not escape"
var buf2 [10]byte // ERROR "moved to heap: buf2"
F2(buf2[:]) // ERROR "buf2 escapes to heap"
var buf3 [10]byte
F3(buf3[:]) // ERROR "buf3 does not escape"
var buf4 [10]byte // ERROR "moved to heap: buf4"
F4(buf4[:]) // ERROR "buf4 escapes to heap"
}
type Tm struct {
x int
}
func (t *Tm) M() { // ERROR "t does not escape"
}
func foo141() {
var f func()
t := new(Tm) // ERROR "escapes to heap"
f = t.M // ERROR "t.M does not escape"
_ = f
}
var gf func()
func foo142() {
t := new(Tm) // ERROR "escapes to heap"
gf = t.M // ERROR "t.M escapes to heap"
}
// errorcheck -0 -m -l
// Copyright 2012 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.
// Test, using compiler diagnostic flags, that the escape analysis is working.
// Compiles but does not run. Inlining is disabled.
package foo
func noleak(p *int) int { // ERROR "p does not escape"
return *p
}
func leaktoret(p *int) *int { // ERROR "leaking param: p to result"
return p
}
func leaktoret2(p *int) (*int, *int) { // ERROR "leaking param: p to result .anon1" "leaking param: p to result .anon2"
return p, p
}
func leaktoret22(p, q *int) (*int, *int) { // ERROR "leaking param: p to result .anon2" "leaking param: q to result .anon3"
return p, q
}
func leaktoret22b(p, q *int) (*int, *int) { // ERROR "leaking param: p to result .anon3" "leaking param: q to result .anon2"
return leaktoret22(q, p)
}
func leaktoret22c(p, q *int) (*int, *int) { // ERROR "leaking param: p to result .anon3" "leaking param: q to result .anon2"
r, s := leaktoret22(q, p)
return r, s
}
func leaktoret22d(p, q *int) (r, s *int) { // ERROR "leaking param: p to result s" "leaking param: q to result r"
r, s = leaktoret22(q, p)
return
}
func leaktoret22e(p, q *int) (r, s *int) { // ERROR "leaking param: p to result s" "leaking param: q to result r"
r, s = leaktoret22(q, p)
return r, s
}
func leaktoret22f(p, q *int) (r, s *int) { // ERROR "leaking param: p to result s" "leaking param: q to result r"
rr, ss := leaktoret22(q, p)
return rr, ss
}
var gp *int
func leaktosink(p *int) *int { // ERROR "leaking param: p"
gp = p
return p
}
func f1() {
var x int
p := noleak(&x) // ERROR "&x does not escape"
_ = p
}
func f2() {
var x int
p := leaktoret(&x) // ERROR "&x does not escape"
_ = p
}
func f3() {
var x int // ERROR "moved to heap: x"
p := leaktoret(&x) // ERROR "&x escapes to heap"
gp = p
}
func f4() {
var x int // ERROR "moved to heap: x"
p, q := leaktoret2(&x) // ERROR "&x escapes to heap"
gp = p
gp = q
}
func f5() {
var x int
leaktoret22(leaktoret2(&x)) // ERROR "&x does not escape"
}
func f6() {
var x int // ERROR "moved to heap: x"
px1, px2 := leaktoret22(leaktoret2(&x)) // ERROR "&x escapes to heap"
gp = px1
_ = px2
}
type T struct{ x int }
func (t *T) Foo(u int) (*T, bool) { // ERROR "leaking param: t to result"
t.x += u
return t, true
}
func f7() *T {
r, _ := new(T).Foo(42) // ERROR "new.T. escapes to heap"
return r
}
func leakrecursive1(p, q *int) (*int, *int) { // ERROR "leaking param: p" "leaking param: q"
return leakrecursive2(q, p)
}
func leakrecursive2(p, q *int) (*int, *int) { // ERROR "leaking param: p" "leaking param: q"
if *p > *q {
return leakrecursive1(q, p)
}
// without this, leakrecursive? are safe for p and q, b/c in fact their graph does not have leaking edges.
return p, q
}
var global interface{}
type T1 struct {
X *int
}
type T2 struct {
Y *T1
}
func f8(p *T1) (k T2) { // ERROR "leaking param: p to result k" "leaking param: p"
if p == nil {
k = T2{}
return
}
global = p // should make p leak always
return T2{p}
}
func f9() {
var j T1 // ERROR "moved to heap: j"
f8(&j) // ERROR "&j escapes to heap"
}
...@@ -7,5 +7,5 @@ ...@@ -7,5 +7,5 @@
package main package main
func f (x, // GCCGO_ERROR "previous" func f (x, // GCCGO_ERROR "previous"
x int) { // ERROR "redeclared|redefinition" "duplicate" x int) { // ERROR "duplicate argument|redefinition"
} }
// $G $D/$F.dir/bug0.go && errchk $G $D/$F.dir/bug1.go // errorcheckdir
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
ignored package ignored
...@@ -20,7 +20,7 @@ Bus error ...@@ -20,7 +20,7 @@ Bus error
/* expected scope hierarchy (outermost to innermost) /* expected scope hierarchy (outermost to innermost)
universe scope (contains predeclared identifiers int, float, int32, len, etc.) universe scope (contains predeclared identifiers int, float32, int32, len, etc.)
"solar" scope (just holds the package name P so it can be found but doesn't conflict) "solar" scope (just holds the package name P so it can be found but doesn't conflict)
global scope (the package global scope) global scope (the package global scope)
local scopes (function scopes) local scopes (function scopes)
......
// $G $D/$F.dir/bug0.go && $G $D/$F.dir/bug1.go && errchk $G $D/$F.dir/bug2.go // errorcheckdir
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
ignored package ignored
// $G $D/bug160.dir/x.go && $G $D/bug160.dir/y.go && $L y.$A && ./$A.out // rundir
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
nothing to see here package ignored
// Copyright 2009 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 main
import . "./a"
import . "./b"
var _ T
var _ V
func main() {
}
// $G $D/bug191.dir/a.go && $G $D/bug191.dir/b.go && $G $D/$F.go && $L $F.$A // rundir
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package main // Tests bug with dot imports.
import . "./a"
import . "./b"
var _ T
var _ V
func main() { package ignored
}
...@@ -11,8 +11,8 @@ var s string; ...@@ -11,8 +11,8 @@ var s string;
var m map[string]int; var m map[string]int;
func main() { func main() {
println(t["hi"]); // ERROR "integer" println(t["hi"]); // ERROR "non-integer slice index|must be integer"
println(s["hi"]); // ERROR "integer" "to type uint" println(s["hi"]); // ERROR "non-integer string index|must be integer"
println(m[0]); // ERROR "map index" println(m[0]); // ERROR "cannot use.*as type string"
} }
...@@ -12,7 +12,7 @@ func g(x int, y float32) (...) // ERROR "[.][.][.]" "final argument" ...@@ -12,7 +12,7 @@ func g(x int, y float32) (...) // ERROR "[.][.][.]" "final argument"
func h(x, y ...int) // ERROR "[.][.][.]" func h(x, y ...int) // ERROR "[.][.][.]"
func i(x int, y ...int, z float) // ERROR "[.][.][.]" func i(x int, y ...int, z float32) // ERROR "[.][.][.]"
var x ...int; // ERROR "[.][.][.]|syntax|type" var x ...int; // ERROR "[.][.][.]|syntax|type"
......
...@@ -12,4 +12,4 @@ var c [1.5]int // ERROR "truncated" ...@@ -12,4 +12,4 @@ var c [1.5]int // ERROR "truncated"
var d ["abc"]int // ERROR "invalid array bound|not numeric" var d ["abc"]int // ERROR "invalid array bound|not numeric"
var e [nil]int // ERROR "invalid array bound|not numeric" var e [nil]int // ERROR "invalid array bound|not numeric"
var f [e]int // ERROR "invalid array bound|not constant" var f [e]int // ERROR "invalid array bound|not constant"
var g [1<<65]int // ERROR "overflows" var g [1<<65]int // ERROR "array bound is too large|overflows"
...@@ -11,5 +11,5 @@ package main ...@@ -11,5 +11,5 @@ package main
type ByteSize float64 type ByteSize float64
const ( const (
_ = iota; // ignore first value by assigning to blank identifier _ = iota; // ignore first value by assigning to blank identifier
KB ByteSize = 1<<(10*X) // ERROR "undefined" "as type ByteSize" KB ByteSize = 1<<(10*X) // ERROR "undefined" "is not a constant|as type ByteSize"
) )
// errchk $G -e $D/$F.dir/[ab].go // errorcheckdir
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2010 The Go Authors. All rights reserved. // Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
......
// $G $D/$F.dir/lib.go && $G $D/$F.dir/main.go && $L main.$A && ./$A.out || echo BUG: fails incorrectly // rundir
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2011 The Go Authors. All rights reserved. // Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Test case for issue 1402. // Test case for issue 1402.
ignored package ignored
// $G $D/$F.dir/p.go && $G $D/$F.dir/main.go && $L main.$A && ./$A.out // rundir
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2011 The Go Authors. All rights reserved. // Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Test case for issue 1550 // Test case for issue 1550: a type cannot implement an interface
ignored // from another package with a private method, and type assertions
// should fail.
package ignored
...@@ -9,11 +9,7 @@ ...@@ -9,11 +9,7 @@
package p package p
type a interface { type a interface {
foo(x int) (x int) // ERROR "redeclared|redefinition" foo(x int) (x int) // ERROR "duplicate argument|redefinition"
}
var b interface {
bar(y int) (y int) // ERROR "redeclared|redefinition"
} }
/* /*
......
...@@ -15,7 +15,7 @@ func bla1() bool { ...@@ -15,7 +15,7 @@ func bla1() bool {
func bla5() bool { func bla5() bool {
_ = 1 _ = 1
false // ERROR "false not used|value computed is not used" false // ERROR "false evaluated but not used|value computed is not used"
_ = 2 _ = 2
return false return false
} }
......
// $G $D/$F.dir/p.go && $G $D/$F.dir/main.go && $L main.$A && ./$A.out || echo BUG: should not fail // rundir
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2011 The Go Authors. All rights reserved. // Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Issue 1536: bug when handling imported interfaces with
// private methods.
package ignored package ignored
...@@ -14,5 +14,5 @@ ...@@ -14,5 +14,5 @@
package main package main
func main() { func main() {
1 + 2 // ERROR "1 \+ 2 not used|value computed is not used" 1 + 2 // ERROR "1 \+ 2 evaluated but not used|value computed is not used"
} }
// Copyright 2011 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
// Issue 2529
package main
import "./pkg"
var x = pkg.E
var fo = struct{ F pkg.T }{F: x}
// $G $D/$F.dir/pkg.go && $G $D/$F.go || echo "Bug 382" // compiledir
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2011 The Go Authors. All rights reserved. // Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file // license that can be found in the LICENSE file
// Issue 2529 // Issue 2529.
package main
import "./pkg"
var x = pkg.E
var fo = struct {F pkg.T}{F: x} package ignored
// [ $A == 6 ] || errchk $G -e $D/$F.go // +build 386 arm
// errorcheck
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2011 The Go Authors. All rights reserved. // Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
...@@ -11,7 +9,7 @@ ...@@ -11,7 +9,7 @@
package main package main
func main() { func main() {
var arr [1000200030]int // ERROR "type .* too large" var arr [1000200030]int // GC_ERROR "type .* too large"
arr_bkup := arr arr_bkup := arr
_ = arr_bkup _ = arr_bkup
} }
\ No newline at end of file
// [ $A != 6 ] || errchk $G -e $D/$F.go // +build amd64
// errorcheck
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2011 The Go Authors. All rights reserved. // Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Issue 2444 // Issue 2444
// Issue 4666: issue with arrays of exactly 4GB.
package main package main
func main() { // ERROR "stack frame too large"
func main() { // GC_ERROR "stack frame too large"
var arr [1000200030]int32 var arr [1000200030]int32
arr_bkup := arr arr_bkup := arr
_ = arr_bkup _ = arr_bkup
} }
func F() { // GC_ERROR "stack frame too large"
var arr [1 << 30]int32
_ = arr[42]
}
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
package p package p
type t struct { type t struct {
x int // ERROR "duplicate field x|duplicate field name .x." x int // GCCGO_ERROR "duplicate field name .x."
x int x int // GC_ERROR "duplicate field x"
} }
func f(t *t) int { func f(t *t) int {
......
...@@ -2,20 +2,20 @@ ...@@ -2,20 +2,20 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package p1 package p1
import "fmt" import "fmt"
type Fer interface { type Fer interface {
f() string f() string
} }
type Object struct {} type Object struct{}
func (this *Object) f() string { func (this *Object) f() string {
return "Object.f" return "Object.f"
} }
func PrintFer(fer Fer) { func PrintFer(fer Fer) {
fmt.Sprintln(fer.f()) fmt.Sprintln(fer.f())
} }
...@@ -2,17 +2,17 @@ ...@@ -2,17 +2,17 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package main package main
import "./p1" import "./p1"
type MyObject struct { type MyObject struct {
p1.Fer p1.Fer
} }
func main() { func main() {
var b p1.Fer = &p1.Object{} var b p1.Fer = &p1.Object{}
p1.PrintFer(b) p1.PrintFer(b)
var c p1.Fer = &MyObject{b} var c p1.Fer = &MyObject{b}
p1.PrintFer(c) p1.PrintFer(c)
} }
// $G $D/$F.dir/p1.go && $G $D/$F.dir/main.go && $L main.$A && ./$A.out // rundir
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2012 The Go Authors. All rights reserved. // Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Issue 1743: test embedding of imported types with private methods.
package ignored package ignored
// Copyright 2012 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.
// Tests that method calls through an interface always
// call the locally defined method localT.m independent
// at which embedding level it is and in which order
// embedding is done.
package main
import "./lib"
import "reflect"
import "fmt"
type localI interface {
m() string
}
type localT struct{}
func (t *localT) m() string {
return "main.localT.m"
}
type myT1 struct {
localT
}
type myT2 struct {
localT
lib.T
}
type myT3 struct {
lib.T
localT
}
func main() {
var i localI
i = new(localT)
if i.m() != "main.localT.m" {
println("BUG: localT:", i.m(), "called")
}
i = new(myT1)
if i.m() != "main.localT.m" {
println("BUG: myT1:", i.m(), "called")
}
i = new(myT2)
if i.m() != "main.localT.m" {
println("BUG: myT2:", i.m(), "called")
}
t3 := new(myT3)
if t3.m() != "main.localT.m" {
println("BUG: t3:", t3.m(), "called")
}
i = new(myT3)
if i.m() != "main.localT.m" {
t := reflect.TypeOf(i)
n := t.NumMethod()
for j := 0; j < n; j++ {
m := t.Method(j)
fmt.Printf("#%d: %s.%s %s\n", j, m.PkgPath, m.Name, m.Type)
}
println("BUG: myT3:", i.m(), "called")
}
var t4 struct {
localT
lib.T
}
if t4.m() != "main.localT.m" {
println("BUG: t4:", t4.m(), "called")
}
i = &t4
if i.m() != "main.localT.m" {
println("BUG: myT4:", i.m(), "called")
}
var t5 struct {
lib.T
localT
}
if t5.m() != "main.localT.m" {
println("BUG: t5:", t5.m(), "called")
}
i = &t5
if i.m() != "main.localT.m" {
println("BUG: myT5:", i.m(), "called")
}
}
// $G $D/$F.dir/lib.go && $G $D/$F.go && $L $F.$A && ./$A.out // rundir
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2012 The Go Authors. All rights reserved. // Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
...@@ -12,91 +9,5 @@ ...@@ -12,91 +9,5 @@
// at which embedding level it is and in which order // at which embedding level it is and in which order
// embedding is done. // embedding is done.
package main package ignored
import "./lib"
import "reflect"
import "fmt"
type localI interface {
m() string
}
type localT struct{}
func (t *localT) m() string {
return "main.localT.m"
}
type myT1 struct {
localT
}
type myT2 struct {
localT
lib.T
}
type myT3 struct {
lib.T
localT
}
func main() {
var i localI
i = new(localT)
if i.m() != "main.localT.m" {
println("BUG: localT:", i.m(), "called")
}
i = new(myT1)
if i.m() != "main.localT.m" {
println("BUG: myT1:", i.m(), "called")
}
i = new(myT2)
if i.m() != "main.localT.m" {
println("BUG: myT2:", i.m(), "called")
}
t3 := new(myT3)
if t3.m() != "main.localT.m" {
println("BUG: t3:", t3.m(), "called")
}
i = new(myT3)
if i.m() != "main.localT.m" {
t := reflect.TypeOf(i)
n := t.NumMethod()
for j := 0; j < n; j++ {
m := t.Method(j)
fmt.Printf("#%d: %s.%s %s\n", j, m.PkgPath, m.Name, m.Type)
}
println("BUG: myT3:", i.m(), "called")
}
var t4 struct {
localT
lib.T
}
if t4.m() != "main.localT.m" {
println("BUG: t4:", t4.m(), "called")
}
i = &t4
if i.m() != "main.localT.m" {
println("BUG: myT4:", i.m(), "called")
}
var t5 struct {
lib.T
localT
}
if t5.m() != "main.localT.m" {
println("BUG: t5:", t5.m(), "called")
}
i = &t5
if i.m() != "main.localT.m" {
println("BUG: myT5:", i.m(), "called")
}
}
// Copyright 2012 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.
// Test converting a type defined in a different package to an
// interface defined in a third package, where the interface has a
// hidden method. This used to cause a link error with gccgo.
package main
import (
"./one"
"./two"
)
func F(i1 one.I1) {
switch v := i1.(type) {
case two.S2:
one.F1(v)
}
}
func main() {
F(nil)
}
// $G $D/$F.dir/one.go && $G $D/$F.dir/two.go && $G $D/$F.go && $L $F.$A && ./$A.out // rundir
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2012 The Go Authors. All rights reserved. // Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
...@@ -11,20 +8,4 @@ ...@@ -11,20 +8,4 @@
// interface defined in a third package, where the interface has a // interface defined in a third package, where the interface has a
// hidden method. This used to cause a link error with gccgo. // hidden method. This used to cause a link error with gccgo.
package main package ignored
import (
"./one"
"./two"
)
func F(i1 one.I1) {
switch v := i1.(type) {
case two.S2:
one.F1(v)
}
}
func main() {
F(nil)
}
// run
// Copyright 2012 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.
// Issue 4138: bug in floating-point registers numbering.
// Makes 6g unable to use more than 11 registers.
package main
func formula() float32 {
mA := [1]float32{1.0}
det1 := mA[0]
det2 := mA[0]
det3 := mA[0]
det4 := mA[0]
det5 := mA[0]
det6 := mA[0]
det7 := mA[0]
det8 := mA[0]
det9 := mA[0]
det10 := mA[0]
det11 := mA[0]
det12 := mA[0]
return det1 + det2*det3 +
det4*det5 + det6*det7 +
det8*det9 + det10*det11 +
det12
}
func main() {
x := formula()
if x != 7.0 {
println(x, 7.0)
panic("x != 7.0")
}
}
// run
// Copyright 2012 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.
// Issue 4173
package main
func main() {
var arr *[10]int
s := 0
for i, _ := range arr {
// used to panic trying to access arr[i]
s += i
}
if s != 45 {
println("BUG")
}
}
// run
// Copyright 2012 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.
// Issue 4156: out of fixed registers when chaining method calls.
// Used to happen with 6g.
package main
type test_i interface {
Test() test_i
Result() bool
}
type test_t struct {
}
func newTest() *test_t {
return &test_t{}
}
type testFn func(string) testFn
func main() {
test := newTest()
switch {
case test.
Test().
Test().
Test().
Test().
Test().
Test().
Test().
Test().
Test().
Test().
Result():
// case worked
default:
panic("Result returned false unexpectedly")
}
}
func (t *test_t) Test() test_i {
return t
}
func (t *test_t) Result() bool {
return true
}
// run
// Copyright 2012 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.
// Issue 3907: out of fixed registers in nested byte multiply.
// Used to happen with both 6g and 8g.
package main
func F(a, b, c, d uint8) uint8 {
return a * (b * (c * (d *
(a * (b * (c * (d *
(a * (b * (c * (d *
a * (b * (c * d)))))))))))))
}
func main() {
var a, b, c, d uint8 = 1, 1, 1, 1
x := F(a, b, c, d)
if x != 1 {
println(x)
panic("x != 1")
}
}
// run
// Copyright 2012 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.
// Issue 4197: growing a slice of zero-width elements
// panics on a division by zero.
package main
func main() {
var x []struct{}
x = append(x, struct{}{})
}
// compile
// Copyright 2012 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.
// Issue 4200: 6g crashes when a type is larger than 4GB.
package main
import "unsafe"
// N=16 on 32-bit arches, 256 on 64-bit arches.
// On 32-bit arches we don't want to test types
// that are over 4GB large.
const N = 1 << unsafe.Sizeof(uintptr(0))
type T [N][10][10][10][10][3]byte
func F(t *T) byte {
return t[0][0][0][0][0][0]
}
// errorcheck
// Copyright 2012 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.
// Issue 3890: missing detection of init loop involving
// method calls in function bodies.
package flag
var commandLine = NewFlagSet() // ERROR "loop|depends upon itself"
type FlagSet struct {
}
func (f *FlagSet) failf(format string, a ...interface{}) {
f.usage()
}
func (f *FlagSet) usage() {
if f == commandLine {
panic(3)
}
}
func NewFlagSet() *FlagSet {
f := &FlagSet{}
f.setErrorHandling(true)
return f
}
func (f *FlagSet) setErrorHandling(b bool) {
f.failf("DIE")
}
// Copyright 2012 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 a
type Foo struct {
int
}
// Copyright 2012 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 b
import "./a"
var x a.Foo
func main() {
x.int = 20 // ERROR "unexported field"
}
// errorcheckdir
// Copyright 2012 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.
// part one of issue 4124. Make sure that the compiler rejects access attempts.
package ignored
// run
// Copyright 2012 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.
// part two of issue 4124. Make sure reflect doesn't mark the field as exported.
package main
import "reflect"
var T struct {
int
}
func main() {
v := reflect.ValueOf(&T)
v = v.Elem().Field(0)
if v.CanSet() {
panic("int should be unexported")
}
}
// errorcheck
// Copyright 2012 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 main
import "os"
type T struct {
File int
}
func main() {
_ = T {
os.File: 1, // ERROR "unknown T? ?field"
}
}
// errorcheck
// Copyright 2012 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.
// Issue 3757: unhelpful typechecking loop message
// for constants that refer to themselves.
package main
const a = a // ERROR "refers to itself|definition loop"
const (
X = A
A = B // ERROR "refers to itself|definition loop"
B = D
C, D = 1, A
)
func main() {
}
// errorcheck
// Copyright 2012 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.
// Issue 3937: unhelpful typechecking loop message
// for identifiers wrongly used as types.
package main
func foo(x foo) {} // ERROR "expected type|not a type"
// Copyright 2012 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 a
type T struct{ A, B int }
type A []int
type M map[int]int
func F1() int {
if (T{1, 2}) == (T{3, 4}) {
return 1
}
return 0
}
func F2() int {
if (M{1: 2}) == nil {
return 1
}
return 0
}
func F3() int {
if nil == (A{}) {
return 1
}
return 0
}
func F4() int {
if a := (A{}); a == nil {
return 1
}
return 0
}
func F5() int {
for k, v := range (M{1: 2}) {
return v - k
}
return 0
}
func F6() int {
switch a := (T{1, 1}); a == (T{1, 2}) {
default:
return 1
}
return 0
}
func F7() int {
for m := (M{}); len(m) < (T{1, 2}).A; m[1] = (A{1})[0] {
return 1
}
return 0
}
func F8() int {
if a := (&T{1, 1}); a != nil {
return 1
}
return 0
}
func F9() int {
var a *T
if a = (&T{1, 1}); a != nil {
return 1
}
return 0
}
// Copyright 2012 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 main
import "./a"
func main() {
for _, f := range []func() int{
a.F1, a.F2, a.F3, a.F4,
a.F5, a.F6, a.F7, a.F8, a.F9} {
if f() > 1 {
panic("f() > 1")
}
}
}
// rundir
// Copyright 2012 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.
// Issue 4230: inlining bug for composite literal in
// if, for, switch statements.
package ignored
// Copyright 2012 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 a
const N = 2+3i
func Func() []complex128 {
return []complex128{1, complex(2, 3), complex(4, 5)}
}
func Mul(z complex128) complex128 {
return z * (3 + 4i)
}
// Copyright 2012 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 main
import "./a"
func main() {
s := a.Func()
if s[0] != 1 {
println(s[0])
panic("s[0] != 1")
}
if s[1] != 2+3i {
println(s[1])
panic("s[1] != 2+3i")
}
if s[2] != 4+5i {
println(s[2])
panic("s[2] != 4+5i")
}
x := 1 + 2i
y := a.Mul(x)
if y != (1+2i)*(3+4i) {
println(y)
panic("y != (1+2i)*(3+4i)")
}
}
// rundir
// Copyright 2012 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.
// Issue 4159: exported inlinable functions squash
// complex literals "a+bi" to "a+b".
package ignored
package p1
type SockaddrUnix int
func (s SockaddrUnix) Error() string { return "blah" }
package p2
import "./p1"
func SockUnix() error { var s *p1.SockaddrUnix; return s }
package main
import "./p2"
func main() {
_ = p2.SockUnix()
}
// compiledir
// Copyright 2012 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.
// Exported data for inlining could forget types of
// local variables declared in inlinable bodies.
package ignored
// Copyright 2012 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 p1
type S struct { X, Y int }
// Copyright 2012 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 main
import (
"reflect"
"./p1"
)
func main() {
var v1 = p1.S{1, 2}
var v2 = struct { X, Y int }{1, 2}
v1 = v2
t1 := reflect.TypeOf(v1)
t2 := reflect.TypeOf(v2)
if !t1.AssignableTo(t2) {
panic(0)
}
if !t2.AssignableTo(t1) {
panic(1)
}
}
// rundir
// Copyright 2012 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.
// The reflect package was not correctly checking field names
// when checking for struct assignability.
package ignored
// run
// Copyright 2012 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.
// Converting constants between types must introduce rounding.
package main
import "fmt"
const (
F32 = 0.00999999977648258209228515625
F64 = 0.01000000000000000020816681711721685132943093776702880859375
)
var F = float64(float32(0.01))
func main() {
// 0.01 rounded to float32 then to float64 is F32.
// 0.01 represented directly in float64 is F64.
if F != F32 {
panic(fmt.Sprintf("F=%.1000g, want %.1000g", F, F32))
}
}
// compile
// Copyright 2012 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.
// Caused an internal compiler error in gccgo.
package p
type C chan struct{}
func (c C) F() {
select {
case c <- struct{}{}:
default:
}
}
// Copyright 2013 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 p1
import "runtime"
func E() func() int { return runtime.NumCPU }
func F() func() { return runtime.Gosched }
func G() func() string { return runtime.GOROOT }
func H() func() { return runtime.GC }
func I() func() string { return runtime.Version }
// Copyright 2013 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 p2
import "runtime"
func E() func() int { return runtime.NumCPU }
func F() func() { return runtime.GC }
func G() func() string { return runtime.GOROOT }
func H() func() { return runtime.Gosched }
func I() func() string { return runtime.Version }
// Copyright 2013 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 main
import (
_ "./p1"
_ "./p2"
)
func main() {
}
// rundir
// Copyright 2013 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.
// Linker would incorrectly parse export data and think
// definitions are inconsistent.
package ignored
// run
// Copyright 2013 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.
// Used to be miscompiled by gccgo, due to a bug in handling
// initialization ordering.
package main
func F(a ...interface{}) interface{} {
s := 0
for _, v := range a {
s += v.(int)
}
return s
}
var V1 = F(V10, V4, V3, V11)
var V2 = F(V1)
var V3 = F(1)
var V4 = F(2)
var V5 = F(3)
var V6 = F(4)
var V7 = F(5)
var V8 = F(V14, V7, V3, V6, V5)
var V9 = F(V4, F(V12))
var V10 = F(V4, V9)
var V11 = F(6)
var V12 = F(V5, V3, V8)
var V13 = F(7)
var V14 = F(8)
func expect(name string, a interface{}, b int) {
if a.(int) != b {
panic(name)
}
}
func main() {
expect("V1", V1, 38)
expect("V2", V2, 38)
expect("V3", V3, 1)
expect("V4", V4, 2)
expect("V5", V5, 3)
expect("V6", V6, 4)
expect("V7", V7, 5)
expect("V8", V8, 21)
expect("V9", V9, 27)
expect("V10", V10, 29)
expect("V11", V11, 6)
expect("V12", V12, 25)
expect("V13", V13, 7)
expect("V14", V14, 8)
}
// run
// Copyright 2013 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.
// Bug in method values: escape analysis was off.
package main
import "sync"
var called = false
type T struct {
once sync.Once
}
func (t *T) M() {
called = true
}
func main() {
var t T
t.once.Do(t.M)
if !called {
panic("not called")
}
}
// run
// Copyright 2012 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.
// Issue 2615: a long chain of else if's causes an overflow
// in the parser stack.
package main
// test returns the index of the lowest set bit in a 256-bit vector.
func test(x [4]uint64) int {
if x[0]&(1<<0) != 0 {
return 0
} else if x[0]&(1<<1) != 0 {
return 1
} else if x[0]&(1<<2) != 0 {
return 2
} else if x[0]&(1<<3) != 0 {
return 3
} else if x[0]&(1<<4) != 0 {
return 4
} else if x[0]&(1<<5) != 0 {
return 5
} else if x[0]&(1<<6) != 0 {
return 6
} else if x[0]&(1<<7) != 0 {
return 7
} else if x[0]&(1<<8) != 0 {
return 8
} else if x[0]&(1<<9) != 0 {
return 9
} else if x[0]&(1<<10) != 0 {
return 10
} else if x[0]&(1<<11) != 0 {
return 11
} else if x[0]&(1<<12) != 0 {
return 12
} else if x[0]&(1<<13) != 0 {
return 13
} else if x[0]&(1<<14) != 0 {
return 14
} else if x[0]&(1<<15) != 0 {
return 15
} else if x[0]&(1<<16) != 0 {
return 16
} else if x[0]&(1<<17) != 0 {
return 17
} else if x[0]&(1<<18) != 0 {
return 18
} else if x[0]&(1<<19) != 0 {
return 19
} else if x[0]&(1<<20) != 0 {
return 20
} else if x[0]&(1<<21) != 0 {
return 21
} else if x[0]&(1<<22) != 0 {
return 22
} else if x[0]&(1<<23) != 0 {
return 23
} else if x[0]&(1<<24) != 0 {
return 24
} else if x[0]&(1<<25) != 0 {
return 25
} else if x[0]&(1<<26) != 0 {
return 26
} else if x[0]&(1<<27) != 0 {
return 27
} else if x[0]&(1<<28) != 0 {
return 28
} else if x[0]&(1<<29) != 0 {
return 29
} else if x[0]&(1<<30) != 0 {
return 30
} else if x[0]&(1<<31) != 0 {
return 31
} else if x[0]&(1<<32) != 0 {
return 32
} else if x[0]&(1<<33) != 0 {
return 33
} else if x[0]&(1<<34) != 0 {
return 34
} else if x[0]&(1<<35) != 0 {
return 35
} else if x[0]&(1<<36) != 0 {
return 36
} else if x[0]&(1<<37) != 0 {
return 37
} else if x[0]&(1<<38) != 0 {
return 38
} else if x[0]&(1<<39) != 0 {
return 39
} else if x[0]&(1<<40) != 0 {
return 40
} else if x[0]&(1<<41) != 0 {
return 41
} else if x[0]&(1<<42) != 0 {
return 42
} else if x[0]&(1<<43) != 0 {
return 43
} else if x[0]&(1<<44) != 0 {
return 44
} else if x[0]&(1<<45) != 0 {
return 45
} else if x[0]&(1<<46) != 0 {
return 46
} else if x[0]&(1<<47) != 0 {
return 47
} else if x[0]&(1<<48) != 0 {
return 48
} else if x[0]&(1<<49) != 0 {
return 49
} else if x[0]&(1<<50) != 0 {
return 50
} else if x[0]&(1<<51) != 0 {
return 51
} else if x[0]&(1<<52) != 0 {
return 52
} else if x[0]&(1<<53) != 0 {
return 53
} else if x[0]&(1<<54) != 0 {
return 54
} else if x[0]&(1<<55) != 0 {
return 55
} else if x[0]&(1<<56) != 0 {
return 56
} else if x[0]&(1<<57) != 0 {
return 57
} else if x[0]&(1<<58) != 0 {
return 58
} else if x[0]&(1<<59) != 0 {
return 59
} else if x[0]&(1<<60) != 0 {
return 60
} else if x[0]&(1<<61) != 0 {
return 61
} else if x[0]&(1<<62) != 0 {
return 62
} else if x[0]&(1<<63) != 0 {
return 63
} else if x[1]&(1<<0) != 0 {
return 64
} else if x[1]&(1<<1) != 0 {
return 65
} else if x[1]&(1<<2) != 0 {
return 66
} else if x[1]&(1<<3) != 0 {
return 67
} else if x[1]&(1<<4) != 0 {
return 68
} else if x[1]&(1<<5) != 0 {
return 69
} else if x[1]&(1<<6) != 0 {
return 70
} else if x[1]&(1<<7) != 0 {
return 71
} else if x[1]&(1<<8) != 0 {
return 72
} else if x[1]&(1<<9) != 0 {
return 73
} else if x[1]&(1<<10) != 0 {
return 74
} else if x[1]&(1<<11) != 0 {
return 75
} else if x[1]&(1<<12) != 0 {
return 76
} else if x[1]&(1<<13) != 0 {
return 77
} else if x[1]&(1<<14) != 0 {
return 78
} else if x[1]&(1<<15) != 0 {
return 79
} else if x[1]&(1<<16) != 0 {
return 80
} else if x[1]&(1<<17) != 0 {
return 81
} else if x[1]&(1<<18) != 0 {
return 82
} else if x[1]&(1<<19) != 0 {
return 83
} else if x[1]&(1<<20) != 0 {
return 84
} else if x[1]&(1<<21) != 0 {
return 85
} else if x[1]&(1<<22) != 0 {
return 86
} else if x[1]&(1<<23) != 0 {
return 87
} else if x[1]&(1<<24) != 0 {
return 88
} else if x[1]&(1<<25) != 0 {
return 89
} else if x[1]&(1<<26) != 0 {
return 90
} else if x[1]&(1<<27) != 0 {
return 91
} else if x[1]&(1<<28) != 0 {
return 92
} else if x[1]&(1<<29) != 0 {
return 93
} else if x[1]&(1<<30) != 0 {
return 94
} else if x[1]&(1<<31) != 0 {
return 95
} else if x[1]&(1<<32) != 0 {
return 96
} else if x[1]&(1<<33) != 0 {
return 97
} else if x[1]&(1<<34) != 0 {
return 98
} else if x[1]&(1<<35) != 0 {
return 99
} else if x[1]&(1<<36) != 0 {
return 100
} else if x[1]&(1<<37) != 0 {
return 101
} else if x[1]&(1<<38) != 0 {
return 102
} else if x[1]&(1<<39) != 0 {
return 103
} else if x[1]&(1<<40) != 0 {
return 104
} else if x[1]&(1<<41) != 0 {
return 105
} else if x[1]&(1<<42) != 0 {
return 106
} else if x[1]&(1<<43) != 0 {
return 107
} else if x[1]&(1<<44) != 0 {
return 108
} else if x[1]&(1<<45) != 0 {
return 109
} else if x[1]&(1<<46) != 0 {
return 110
} else if x[1]&(1<<47) != 0 {
return 111
} else if x[1]&(1<<48) != 0 {
return 112
} else if x[1]&(1<<49) != 0 {
return 113
} else if x[1]&(1<<50) != 0 {
return 114
} else if x[1]&(1<<51) != 0 {
return 115
} else if x[1]&(1<<52) != 0 {
return 116
} else if x[1]&(1<<53) != 0 {
return 117
} else if x[1]&(1<<54) != 0 {
return 118
} else if x[1]&(1<<55) != 0 {
return 119
} else if x[1]&(1<<56) != 0 {
return 120
} else if x[1]&(1<<57) != 0 {
return 121
} else if x[1]&(1<<58) != 0 {
return 122
} else if x[1]&(1<<59) != 0 {
return 123
} else if x[1]&(1<<60) != 0 {
return 124
} else if x[1]&(1<<61) != 0 {
return 125
} else if x[1]&(1<<62) != 0 {
return 126
} else if x[1]&(1<<63) != 0 {
return 127
} else if x[2]&(1<<0) != 0 {
return 128
} else if x[2]&(1<<1) != 0 {
return 129
} else if x[2]&(1<<2) != 0 {
return 130
} else if x[2]&(1<<3) != 0 {
return 131
} else if x[2]&(1<<4) != 0 {
return 132
} else if x[2]&(1<<5) != 0 {
return 133
} else if x[2]&(1<<6) != 0 {
return 134
} else if x[2]&(1<<7) != 0 {
return 135
} else if x[2]&(1<<8) != 0 {
return 136
} else if x[2]&(1<<9) != 0 {
return 137
} else if x[2]&(1<<10) != 0 {
return 138
} else if x[2]&(1<<11) != 0 {
return 139
} else if x[2]&(1<<12) != 0 {
return 140
} else if x[2]&(1<<13) != 0 {
return 141
} else if x[2]&(1<<14) != 0 {
return 142
} else if x[2]&(1<<15) != 0 {
return 143
} else if x[2]&(1<<16) != 0 {
return 144
} else if x[2]&(1<<17) != 0 {
return 145
} else if x[2]&(1<<18) != 0 {
return 146
} else if x[2]&(1<<19) != 0 {
return 147
} else if x[2]&(1<<20) != 0 {
return 148
} else if x[2]&(1<<21) != 0 {
return 149
} else if x[2]&(1<<22) != 0 {
return 150
} else if x[2]&(1<<23) != 0 {
return 151
} else if x[2]&(1<<24) != 0 {
return 152
} else if x[2]&(1<<25) != 0 {
return 153
} else if x[2]&(1<<26) != 0 {
return 154
} else if x[2]&(1<<27) != 0 {
return 155
} else if x[2]&(1<<28) != 0 {
return 156
} else if x[2]&(1<<29) != 0 {
return 157
} else if x[2]&(1<<30) != 0 {
return 158
} else if x[2]&(1<<31) != 0 {
return 159
} else if x[2]&(1<<32) != 0 {
return 160
} else if x[2]&(1<<33) != 0 {
return 161
} else if x[2]&(1<<34) != 0 {
return 162
} else if x[2]&(1<<35) != 0 {
return 163
} else if x[2]&(1<<36) != 0 {
return 164
} else if x[2]&(1<<37) != 0 {
return 165
} else if x[2]&(1<<38) != 0 {
return 166
} else if x[2]&(1<<39) != 0 {
return 167
} else if x[2]&(1<<40) != 0 {
return 168
} else if x[2]&(1<<41) != 0 {
return 169
} else if x[2]&(1<<42) != 0 {
return 170
} else if x[2]&(1<<43) != 0 {
return 171
} else if x[2]&(1<<44) != 0 {
return 172
} else if x[2]&(1<<45) != 0 {
return 173
} else if x[2]&(1<<46) != 0 {
return 174
} else if x[2]&(1<<47) != 0 {
return 175
} else if x[2]&(1<<48) != 0 {
return 176
} else if x[2]&(1<<49) != 0 {
return 177
} else if x[2]&(1<<50) != 0 {
return 178
} else if x[2]&(1<<51) != 0 {
return 179
} else if x[2]&(1<<52) != 0 {
return 180
} else if x[2]&(1<<53) != 0 {
return 181
} else if x[2]&(1<<54) != 0 {
return 182
} else if x[2]&(1<<55) != 0 {
return 183
} else if x[2]&(1<<56) != 0 {
return 184
} else if x[2]&(1<<57) != 0 {
return 185
} else if x[2]&(1<<58) != 0 {
return 186
} else if x[2]&(1<<59) != 0 {
return 187
} else if x[2]&(1<<60) != 0 {
return 188
} else if x[2]&(1<<61) != 0 {
return 189
} else if x[2]&(1<<62) != 0 {
return 190
} else if x[2]&(1<<63) != 0 {
return 191
} else if x[3]&(1<<0) != 0 {
return 192
} else if x[3]&(1<<1) != 0 {
return 193
} else if x[3]&(1<<2) != 0 {
return 194
} else if x[3]&(1<<3) != 0 {
return 195
} else if x[3]&(1<<4) != 0 {
return 196
} else if x[3]&(1<<5) != 0 {
return 197
} else if x[3]&(1<<6) != 0 {
return 198
} else if x[3]&(1<<7) != 0 {
return 199
} else if x[3]&(1<<8) != 0 {
return 200
} else if x[3]&(1<<9) != 0 {
return 201
} else if x[3]&(1<<10) != 0 {
return 202
} else if x[3]&(1<<11) != 0 {
return 203
} else if x[3]&(1<<12) != 0 {
return 204
} else if x[3]&(1<<13) != 0 {
return 205
} else if x[3]&(1<<14) != 0 {
return 206
} else if x[3]&(1<<15) != 0 {
return 207
} else if x[3]&(1<<16) != 0 {
return 208
} else if x[3]&(1<<17) != 0 {
return 209
} else if x[3]&(1<<18) != 0 {
return 210
} else if x[3]&(1<<19) != 0 {
return 211
} else if x[3]&(1<<20) != 0 {
return 212
} else if x[3]&(1<<21) != 0 {
return 213
} else if x[3]&(1<<22) != 0 {
return 214
} else if x[3]&(1<<23) != 0 {
return 215
} else if x[3]&(1<<24) != 0 {
return 216
} else if x[3]&(1<<25) != 0 {
return 217
} else if x[3]&(1<<26) != 0 {
return 218
} else if x[3]&(1<<27) != 0 {
return 219
} else if x[3]&(1<<28) != 0 {
return 220
} else if x[3]&(1<<29) != 0 {
return 221
} else if x[3]&(1<<30) != 0 {
return 222
} else if x[3]&(1<<31) != 0 {
return 223
} else if x[3]&(1<<32) != 0 {
return 224
} else if x[3]&(1<<33) != 0 {
return 225
} else if x[3]&(1<<34) != 0 {
return 226
} else if x[3]&(1<<35) != 0 {
return 227
} else if x[3]&(1<<36) != 0 {
return 228
} else if x[3]&(1<<37) != 0 {
return 229
} else if x[3]&(1<<38) != 0 {
return 230
} else if x[3]&(1<<39) != 0 {
return 231
} else if x[3]&(1<<40) != 0 {
return 232
} else if x[3]&(1<<41) != 0 {
return 233
} else if x[3]&(1<<42) != 0 {
return 234
} else if x[3]&(1<<43) != 0 {
return 235
} else if x[3]&(1<<44) != 0 {
return 236
} else if x[3]&(1<<45) != 0 {
return 237
} else if x[3]&(1<<46) != 0 {
return 238
} else if x[3]&(1<<47) != 0 {
return 239
} else if x[3]&(1<<48) != 0 {
return 240
} else if x[3]&(1<<49) != 0 {
return 241
} else if x[3]&(1<<50) != 0 {
return 242
} else if x[3]&(1<<51) != 0 {
return 243
} else if x[3]&(1<<52) != 0 {
return 244
} else if x[3]&(1<<53) != 0 {
return 245
} else if x[3]&(1<<54) != 0 {
return 246
} else if x[3]&(1<<55) != 0 {
return 247
} else if x[3]&(1<<56) != 0 {
return 248
} else if x[3]&(1<<57) != 0 {
return 249
} else if x[3]&(1<<58) != 0 {
return 250
} else if x[3]&(1<<59) != 0 {
return 251
} else if x[3]&(1<<60) != 0 {
return 252
} else if x[3]&(1<<61) != 0 {
return 253
} else if x[3]&(1<<62) != 0 {
return 254
} else if x[3]&(1<<63) != 0 {
return 255
}
return -1
}
func main() {
const ones = ^uint64(0)
for i := 0; i < 256; i++ {
bits := [4]uint64{ones, ones, ones, ones}
// clear bottom i bits
bits[i/64] ^= 1<<(uint(i)&63) - 1
for j := i/64 - 1; j >= 0; j-- {
bits[j] = 0
}
k := test(bits)
if k != i {
print("test(bits)=", k, " want ", i, "\n")
panic("failed")
}
}
}
// $G $D/$F.dir/one.go && $G $D/$F.dir/two.go || echo BUG:bug434 // compiledir
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2011 The Go Authors. All rights reserved. // Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Issue 3552: cross-package inlining misbehaves when
// referencing embedded builtins.
package ignored package ignored
// errorcheck
// Copyright 2012 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 p
func init() // ERROR "missing function body|cannot declare init"
// errorcheck
// Copyright 2012 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 foo
var i int
func (*i) bar() // ERROR "not a type|expected type"
// errorcheck
// Copyright 2012 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 foo
type mybool bool
var x, y = 1, 2
var _ mybool = x < y && x < y // ERROR "cannot use"
var _ mybool = x < y || x < y // ERROR "cannot use"
// errorcheck
// Copyright 2012 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.
// Issue 3925: wrong line number for error message "missing key in map literal"
// also a test for correct line number in other malformed composite literals.
package foo
var _ = map[string]string{
"1": "2",
"3", "4", // ERROR "missing key|must have keys"
}
var _ = []string{
"foo",
"bar",
20, // ERROR "cannot use|incompatible type"
}
// run
// Copyright 2012 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.
// issue 4066: return values not being spilled eagerly enough
package main
func main() {
n := foo()
if n != 2 {
println(n)
panic("wrong return value")
}
}
type terr struct{}
func foo() (val int) {
val = 0
defer func() {
if x := recover(); x != nil {
_ = x.(terr)
}
}()
for {
val = 2
foo1()
}
panic("unreachable")
}
func foo1() {
panic(terr{})
}
// errorcheck
// Copyright 2013 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 main
type T []int
func main() {
_ = make(T, -1) // ERROR "negative"
_ = make(T, 0.5) // ERROR "constant 0.5 truncated to integer|non-integer"
_ = make(T, 1.0) // ok
_ = make(T, 1<<63) // ERROR "len argument too large"
_ = make(T, 0, -1) // ERROR "negative cap"
_ = make(T, 10, 0) // ERROR "len larger than cap"
}
// run
// Copyright 2013 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 main
import (
"strings"
"unsafe"
)
type T []int
func main() {
n := -1
shouldPanic("len out of range", func() {_ = make(T, n)})
shouldPanic("cap out of range", func() {_ = make(T, 0, n)})
var t *byte
if unsafe.Sizeof(t) == 8 {
n = 1<<20
n <<= 20
shouldPanic("len out of range", func() {_ = make(T, n)})
shouldPanic("cap out of range", func() {_ = make(T, 0, n)})
n <<= 20
shouldPanic("len out of range", func() {_ = make(T, n)})
shouldPanic("cap out of range", func() {_ = make(T, 0, n)})
} else {
n = 1<<31 - 1
shouldPanic("len out of range", func() {_ = make(T, n)})
shouldPanic("cap out of range", func() {_ = make(T, 0, n)})
}
}
func shouldPanic(str string, f func()) {
defer func() {
err := recover()
if err == nil {
panic("did not panic")
}
s := err.(error).Error()
if !strings.Contains(s, str) {
panic("got panic " + s + ", want " + str)
}
}()
f()
}
// errorcheck
// Copyright 2012 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 foo
var s [][10]int
const m = len(s[len(s)-1]) // ERROR "is not a constant|is not constant"
// errorcheck -0 -m
// Copyright 2013 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.
// Check go:noescape annotations.
package p
// The noescape comment only applies to the next func,
// which must not have a body.
//go:noescape
func F1([]byte)
func F2([]byte)
func G() {
var buf1 [10]byte
F1(buf1[:]) // ERROR "buf1 does not escape"
var buf2 [10]byte // ERROR "moved to heap: buf2"
F2(buf2[:]) // ERROR "buf2 escapes to heap"
}
// compile
// Copyright 2013 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.
// Issue 4162. Trailing commas now allowed in conversions.
package p
// All these are valid now.
var (
_ = int(1.0,) // comma was always permitted (like function call)
_ = []byte("foo",) // was syntax error: unexpected comma
_ = chan int(nil,) // was syntax error: unexpected comma
_ = (func())(nil,) // was syntax error: unexpected comma
)
// run
// Copyright 2012 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.
// Issue 4167: inlining of a (*T).Method expression taking
// its arguments from a multiple return breaks the compiler.
package main
type pa []int
type p int
func (this *pa) func1() (v *p, c int) {
for _ = range *this {
c++
}
v = (*p)(&c)
return
}
func (this *pa) func2() p {
return (*p).func3(this.func1())
}
func (this *p) func3(f int) p {
return *this
}
func (this *pa) func2dots() p {
return (*p).func3(this.func1())
}
func (this *p) func3dots(f ...int) p {
return *this
}
func main() {
arr := make(pa, 13)
length := arr.func2()
if int(length) != len(arr) {
panic("length != len(arr)")
}
length = arr.func2dots()
if int(length) != len(arr) {
panic("length != len(arr)")
}
}
// errorcheck
// Copyright 2013 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 p
func f() {
var a [10]int
_ = a[-1] // ERROR "invalid array index -1|index out of bounds"
_ = a[-1:] // ERROR "invalid slice index -1|index out of bounds"
_ = a[:-1] // ERROR "invalid slice index -1|index out of bounds"
_ = a[10] // ERROR "invalid array index 10|index out of bounds"
var s []int
_ = s[-1] // ERROR "invalid slice index -1|index out of bounds"
_ = s[-1:] // ERROR "invalid slice index -1|index out of bounds"
_ = s[:-1] // ERROR "invalid slice index -1|index out of bounds"
_ = s[10]
const c = "foo"
_ = c[-1] // ERROR "invalid string index -1|index out of bounds"
_ = c[-1:] // ERROR "invalid slice index -1|index out of bounds"
_ = c[:-1] // ERROR "invalid slice index -1|index out of bounds"
_ = c[3] // ERROR "invalid string index 3|index out of bounds"
var t string
_ = t[-1] // ERROR "invalid string index -1|index out of bounds"
_ = t[-1:] // ERROR "invalid slice index -1|index out of bounds"
_ = t[:-1] // ERROR "invalid slice index -1|index out of bounds"
_ = t[3]
}
// errorcheck
// Copyright 2012 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.
// Issue 4251: slice with inverted range is an error.
package p
func F1(s []byte) []byte {
return s[2:1] // ERROR "inverted"
}
func F2(a [10]byte) []byte {
return a[2:1] // ERROR "inverted"
}
func F3(s string) string {
return s[2:1] // ERROR "inverted"
}
// Copyright 2012 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.
// A package that redeclares common builtin names.
package a
var true = 0 == 1
var false = 0 == 0
var nil = 1
const append = 42
type error bool
type int interface{}
func len(interface{}) int32 { return 42 }
func Test() {
var array [append]int
if true {
panic("unexpected builtin true instead of redeclared one")
}
if !false {
panic("unexpected builtin false instead of redeclared one")
}
if len(array) != 42 {
println(len(array))
panic("unexpected call of builtin len")
}
}
func InlinedFakeTrue() error { return error(true) }
func InlinedFakeFalse() error { return error(false) }
func InlinedFakeNil() int { return nil }
// Copyright 2012 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 main
import "./a"
func main() {
if a.InlinedFakeTrue() {
panic("returned true was the real one")
}
if !a.InlinedFakeFalse() {
panic("returned false was the real one")
}
if a.InlinedFakeNil() == nil {
panic("returned nil was the real one")
}
a.Test()
}
// rundir
// Copyright 2012 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.
// Issue 4252: tests that fixing the issue still allow
// builtins to be redeclared and are not corrupted
// in export data.
package ignored
// errorcheck
// Copyright 2013 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.
// issue 4264: reject int division by const 0
package main
func main() {
var x int
var y float64
var z complex128
println(x/0) // ERROR "division by zero"
println(y/0)
println(z/0)
}
\ No newline at end of file
// errorcheck
// Copyright 2012 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.
// Issue 4283: nil == nil can't be done as the type is unknown.
package p
func F1() bool {
return nil == nil // ERROR "invalid"
}
func F2() bool {
return nil != nil // ERROR "invalid"
}
// run
// Copyright 2012 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.
// Order of operations in select.
package main
func main() {
c := make(chan int, 1)
x := 0
select {
case c <- x: // should see x = 0, not x = 42 (after makec)
case <-makec(&x): // should be evaluated only after c and x on previous line
}
y := <-c
if y != 0 {
panic(y)
}
}
func makec(px *int) chan bool {
if false { for {} }
*px = 42
return make(chan bool, 0)
}
// run
// Copyright 2012 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.
// Issue 4316: the stack overflow check in the linker
// is confused when it encounters a split-stack function
// that needs 0 bytes of stack space.
package main
type Peano *Peano
func makePeano(n int) *Peano {
if n == 0 {
return nil
}
p := Peano(makePeano(n - 1))
return &p
}
var countArg Peano
var countResult int
func countPeano() {
if countArg == nil {
countResult = 0
return
}
countArg = *countArg
countPeano()
countResult++
}
var s = "(())"
var pT = 0
func p() {
if pT >= len(s) {
return
}
if s[pT] == '(' {
pT += 1
p()
if pT < len(s) && s[pT] == ')' {
pT += 1
} else {
return
}
p()
}
}
func main() {
countArg = makePeano(4096)
countPeano()
if countResult != 4096 {
println("countResult =", countResult)
panic("countResult != 4096")
}
p()
}
// compile
// Copyright 2012 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.
// Issue 4323: inlining of functions with local variables
// forgets to typecheck the declarations in the inlined copy.
package main
type reader struct {
C chan T
}
type T struct{ C chan []byte }
var r = newReader()
func newReader() *reader { return new(reader) }
func (r *reader) Read(n int) ([]byte, error) {
req := T{C: make(chan []byte)}
r.C <- req
return <-req.C, nil
}
func main() {
s, err := r.Read(1)
_, _ = s, err
}
package p1
type O map[string]map[string]string
func (opts O) RemoveOption(sect, opt string) bool {
if _, ok := opts[sect]; !ok {
return false
}
_, ok := opts[sect][opt]
delete(opts[sect], opt)
return ok
}
package p2
import "./p1"
func NewO() p1.O { return nil }
package q1
func Deref(typ interface{}) interface{} {
if typ, ok := typ.(*int); ok {
return *typ
}
return typ
}
package main
import "./q1"
func main() {
x := 1
y := q1.Deref(&x)
if y != 1 {
panic("y != 1")
}
}
package z
import "./p2"
func main() {
p2.NewO().RemoveOption("hello", "world")
}
// compiledir
// Copyright 2012 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.
// Printing local variables in inliner shadows global names.
package ignored
// compile
// Copyright 2012 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.
// Issue 4348. After switch to 64-bit ints the compiler generates
// illegal instructions when using large array bounds or indexes.
package main
// 1<<32 on a 64-bit machine, 1 otherwise.
const LARGE = ^uint(0)>>32 + 1
func A() int {
var a []int
return a[LARGE]
}
var b [LARGE]int
func B(i int) int {
return b[i]
}
func main() {
n := A()
B(n)
}
// run
// Copyright 2012 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.
// Issue 4353. An optimizer bug in 8g triggers a runtime fault
// instead of an out of bounds panic.
package main
var aib [100000]int
var paib *[100000]int = &aib
var i64 int64 = 100023
func main() {
defer func() { recover() }()
_ = paib[i64]
}
// errorcheck
// Copyright 2012 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.
// Issue 4359: wrong handling of broken struct fields
// causes "internal compiler error: lookdot badwidth".
package main
type T struct {
x T1 // ERROR "undefined"
}
func f() {
var t *T
_ = t.x
}
// Copyright 2012 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 p1
type Magic int
type T struct {
x interface{}
}
func (t *T) M() bool {
_, ok := t.x.(Magic)
return ok
}
func F(t *T) {
println(t)
}
// Copyright 2012 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 p2
import "./p1"
type T struct {
p1.T
}
func F() {
var t T
p1.F(&t.T)
}
// Copyright 2012 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 p3
import "./p2"
func F() {
p2.F()
var t p2.T
println(t.T.M())
}
// compiledir
// Copyright 2012 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.
// Re-exporting inlined function bodies missed types in x, ok := v.(Type)
package ignored
// run
// Copyright 2012 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.
// Issue 4396. Arrays of bytes are not required to be
// word aligned. 5g should use MOVB to load the address
// of s.g[0] for its nil check.
//
// This test _may_ fail on arm, but requires the host to
// trap unaligned loads. This is generally done with
//
// echo "4" > /proc/cpu/alignment
package main
var s = struct {
// based on lzw.decoder
a, b, c, d, e uint16
f [4096]uint8
g [4096]uint8
}{}
func main() {
s.g[0] = 1
}
// run
// Copyright 2012 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.
// This test _may_ fail on arm, but requires the host to
// trap unaligned loads. This is generally done with
//
// echo "4" > /proc/cpu/alignment
package main
type T struct {
U uint16
V T2
}
type T2 struct {
pad [4096]byte
A, B byte
}
var s, t = new(T), new(T)
func main() {
var u, v *T2 = &s.V, &t.V
u.B = v.B
}
// compile
// Copyright 2012 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.
// Issue 4399: 8g would print "gins LEAQ nil *A".
package main
type A struct{ a int }
func main() {
println(((*A)(nil)).a)
}
// errorcheck
// Copyright 2012 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 p
const (
_ = iota
_ // ERROR "illegal character|invalid character"
_ // ERROR "illegal character|invalid character"
_ // ERROR "illegal character|invalid character"
_ // ERROR "illegal character|invalid character"
)
// errorcheck
// Copyright 2012 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 p
type a struct {
a int
}
func main() {
av := a{};
_ = *a(av); // ERROR "invalid indirect|expected pointer"
}
// run
// Copyright 2012 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.
// Issue 4448: 64-bit indices that are statically known
// to be bounded make 5g and 8g generate a dangling branch.
package main
const b26 uint64 = 0x022fdd63cc95386d
var bitPos [64]int
func init() {
for p := uint(0); p < 64; p++ {
bitPos[b26<<p>>58] = int(p)
}
}
func MinPos(w uint64) int {
if w == 0 {
panic("bit: MinPos(0) undefined")
}
return bitPos[((w&-w)*b26)>>58]
}
func main() {
const one = uint64(1)
for i := 0; i < 64; i++ {
if MinPos(1<<uint(i)) != i {
println("i =", i)
panic("MinPos(1<<uint(i)) != i")
}
}
}
// errorcheck
// Copyright 2013 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.
// Issue 4452. Used to print many errors, now just one.
package main
func main() {
_ = [...]int(4) // ERROR "\[\.\.\.\].*outside of array literal"
}
// errorcheck
// Copyright 2012 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.
// Issue 4458: gc accepts invalid method expressions
// like (**T).Method.
package main
type T struct{}
func (T) foo() {}
func main() {
av := T{}
pav := &av
(**T).foo(&pav) // ERROR "no method foo|requires named type or pointer to named"
}
// errorcheck
// Copyright 2012 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.
// Issue 4463: test builtin functions in statement context and in
// go/defer functions.
package p
import "unsafe"
func F() {
var a []int
var c chan int
var m map[int]int
var s struct{ f int }
append(a, 0) // ERROR "not used"
cap(a) // ERROR "not used"
complex(1, 2) // ERROR "not used"
imag(1i) // ERROR "not used"
len(a) // ERROR "not used"
make([]int, 10) // ERROR "not used"
new(int) // ERROR "not used"
real(1i) // ERROR "not used"
unsafe.Alignof(a) // ERROR "not used"
unsafe.Offsetof(s.f) // ERROR "not used"
unsafe.Sizeof(a) // ERROR "not used"
close(c)
copy(a, a)
delete(m, 0)
panic(0)
print("foo")
println("bar")
recover()
(close(c))
(copy(a, a))
(delete(m, 0))
(panic(0))
(print("foo"))
(println("bar"))
(recover())
go append(a, 0) // ERROR "not used|discards result"
go cap(a) // ERROR "not used|discards result"
go complex(1, 2) // ERROR "not used|discards result"
go imag(1i) // ERROR "not used|discards result"
go len(a) // ERROR "not used|discards result"
go make([]int, 10) // ERROR "not used|discards result"
go new(int) // ERROR "not used|discards result"
go real(1i) // ERROR "not used|discards result"
go unsafe.Alignof(a) // ERROR "not used|discards result"
go unsafe.Offsetof(s.f) // ERROR "not used|discards result"
go unsafe.Sizeof(a) // ERROR "not used|discards result"
go close(c)
go copy(a, a)
go delete(m, 0)
go panic(0)
go print("foo")
go println("bar")
go recover()
defer append(a, 0) // ERROR "not used|discards result"
defer cap(a) // ERROR "not used|discards result"
defer complex(1, 2) // ERROR "not used|discards result"
defer imag(1i) // ERROR "not used|discards result"
defer len(a) // ERROR "not used|discards result"
defer make([]int, 10) // ERROR "not used|discards result"
defer new(int) // ERROR "not used|discards result"
defer real(1i) // ERROR "not used|discards result"
defer unsafe.Alignof(a) // ERROR "not used|discards result"
defer unsafe.Offsetof(s.f) // ERROR "not used|discards result"
defer unsafe.Sizeof(a) // ERROR "not used|discards result"
defer close(c)
defer copy(a, a)
defer delete(m, 0)
defer panic(0)
defer print("foo")
defer println("bar")
defer recover()
}
// errorcheck
// Copyright 2012 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.
// Issue 4468: go/defer calls may not be parenthesized.
package p
type T int
func (t *T) F() T {
return *t
}
type S struct {
t T
}
func F() {
go (F()) // ERROR "must be function call"
defer (F()) // ERROR "must be function call"
var s S
(&s.t).F()
go (&s.t).F()
defer (&s.t).F()
}
// errorcheck
// Copyright 2012 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.
// Issue 4470: parens are not allowed around .(type) "expressions"
package main
func main() {
var i interface{}
switch (i.(type)) { // ERROR "outside type switch"
default:
}
}
// run
// Copyright 2012 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 main
type I interface {
m() int
}
type T struct{}
func (T) m() int {
return 3
}
var t T
var ret = I.m(t)
func main() {
if ret != 3 {
println("ret = ", ret)
panic("ret != 3")
}
}
// Copyright 2012 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 p
import "fmt" // ERROR "fmt redeclared|imported"
var _ = fmt.Printf
// Copyright 2012 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 p
func fmt() {}
// errorcheckdir
// Copyright 2012 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 ignored
// errorcheck
// Copyright 2012 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 p
var init = 1 // ERROR "cannot declare init - must be func"
// errorcheck
// Copyright 2012 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 p
const init = 1 // ERROR "cannot declare init - must be func"
// errorcheck
// Copyright 2012 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 p
type init byte // ERROR "cannot declare init - must be func"
// run
// Copyright 2012 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.
// Issue 4518. In some circumstances "return F(...)"
// where F has multiple returns is miscompiled by 6g due to
// bold assumptions in componentgen.
package main
func DontInline() {}
func F(e interface{}) (int, int) {
DontInline()
return 3, 7
}
func G() (int, int) {
DontInline()
return 3, 7
}
func bogus1(d interface{}) (int, int) {
switch {
default:
return F(d)
}
return 0, 0
}
func bogus2() (int, int) {
switch {
default:
return F(3)
}
return 0, 0
}
func bogus3(d interface{}) (int, int) {
switch {
default:
return G()
}
return 0, 0
}
func bogus4() (int, int) {
switch {
default:
return G()
}
return 0, 0
}
func check(a, b int) {
if a != 3 || b != 7 {
println(a, b)
panic("a != 3 || b != 7")
}
}
func main() {
check(bogus1(42))
check(bogus2())
}
// compile
// Copyright 2012 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.
// Issue 4529: escape analysis crashes on "go f(g())"
// when g has multiple returns.
package main
type M interface{}
type A struct {
a string
b chan M
}
func (a *A) I() (b <-chan M, c chan<- M) {
a.b, c = make(chan M), make(chan M)
b = a.b
return
}
func Init(a string, b *A, c interface {
I() (<-chan M, chan<- M)
}) {
b.a = a
go b.c(c.I())
}
func (a *A) c(b <-chan M, _ chan<- M) {}
// errorcheck
// Copyright 2012 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.
// Issue 4545: untyped constants are incorrectly coerced
// to concrete types when used in interface{} context.
package main
import "fmt"
func main() {
var s uint
fmt.Println(1.0 + 1<<s) // ERROR "invalid operation|non-integer type|incompatible type"
x := 1.0 + 1<<s // ERROR "invalid operation|non-integer type"
_ = x
}
// run
// Copyright 2012 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 main
import (
"fmt"
"runtime"
"strings"
)
type T struct {
val int
}
func main() {
defer expectError(22)
var pT *T
switch pT.val { // error should be here - line 22
case 0:
fmt.Println("0")
case 1: // used to show up here instead
fmt.Println("1")
case 2:
fmt.Println("2")
}
fmt.Println("finished")
}
func expectError(expectLine int) {
if recover() == nil {
panic("did not crash")
}
for i := 1;; i++ {
_, file, line, ok := runtime.Caller(i)
if !ok {
panic("cannot find issue4562.go on stack")
}
if strings.HasSuffix(file, "issue4562.go") {
if line != expectLine {
panic(fmt.Sprintf("crashed at line %d, wanted line %d", line, expectLine))
}
break
}
}
}
// run
// Copyright 2013 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.
// Issue 4585: comparisons and hashes process blank
// fields and padding in structs.
package main
import "unsafe"
// T is a structure with padding.
type T struct {
A int16
B int64
C int16
D int64
Dummy [64]byte
}
// U is a structure with a blank field
type U struct {
A, _, B int
Dummy [64]byte
}
// USmall is like U but the frontend will inline comparison
// instead of calling the generated eq function.
type USmall struct {
A, _, B int32
}
// V has padding but not on the first field.
type V struct {
A1, A2, A3 int32
B int16
C int32
}
// W has padding at the end.
type W struct {
A1, A2, A3 int32
B int32
C int8
}
func test1() {
var a, b U
m := make(map[U]int)
copy((*[16]byte)(unsafe.Pointer(&a))[:], "hello world!")
a.A, a.B = 1, 2
b.A, b.B = 1, 2
if a != b {
panic("broken equality: a != b")
}
m[a] = 1
m[b] = 2
if len(m) == 2 {
panic("broken hash: len(m) == 2")
}
if m[a] != 2 {
panic("m[a] != 2")
}
}
func test2() {
var a, b T
m := make(map[T]int)
copy((*[16]byte)(unsafe.Pointer(&a))[:], "hello world!")
a.A, a.B, a.C, a.D = 1, 2, 3, 4
b.A, b.B, b.C, b.D = 1, 2, 3, 4
if a != b {
panic("broken equality: a != b")
}
m[a] = 1
m[b] = 2
if len(m) == 2 {
panic("broken hash: len(m) == 2")
}
if m[a] != 2 {
panic("m[a] != 2")
}
}
func test3() {
var a, b USmall
copy((*[12]byte)(unsafe.Pointer(&a))[:], "hello world!")
a.A, a.B = 1, 2
b.A, b.B = 1, 2
if a != b {
panic("broken equality: a != b")
}
}
func test4() {
var a, b V
m := make(map[V]int)
copy((*[20]byte)(unsafe.Pointer(&a))[:], "Hello World, Gopher!")
a.A1, a.A2, a.A3, a.B, a.C = 1, 2, 3, 4, 5
b.A1, b.A2, b.A3, b.B, b.C = 1, 2, 3, 4, 5
if a != b {
panic("broken equality: a != b")
}
m[a] = 1
m[b] = 2
if len(m) == 2 {
panic("broken hash: len(m) == 2")
}
if m[a] != 2 {
panic("m[a] != 2")
}
}
func test5() {
var a, b W
m := make(map[W]int)
copy((*[20]byte)(unsafe.Pointer(&a))[:], "Hello World, Gopher!")
a.A1, a.A2, a.A3, a.B, a.C = 1, 2, 3, 4, 5
b.A1, b.A2, b.A3, b.B, b.C = 1, 2, 3, 4, 5
if a != b {
panic("broken equality: a != b")
}
m[a] = 1
m[b] = 2
if len(m) == 2 {
panic("broken hash: len(m) == 2")
}
if m[a] != 2 {
panic("m[a] != 2")
}
}
func main() {
test1()
test2()
test3()
test4()
test5()
}
// Copyright 2012 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 pkg1
type A interface {
Write() error
}
type B interface {
Hello()
world()
}
type C struct{}
func (c C) Write() error { return nil }
var T = struct{ A }{nil}
var U = struct{ B }{nil}
var V A = struct{ *C }{nil}
var W = interface {
Write() error
Hello()
}(nil)
// Copyright 2012 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 pkg2
import "./pkg1"
var T = struct{ pkg1.A }{nil}
var U = struct{ pkg1.B }{nil}
var V pkg1.A = struct{ *pkg1.C }{nil}
var W = interface {
Write() error
Hello()
}(nil)
// Copyright 2012 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 main
import (
"./pkg1"
"./pkg2"
)
func main() {
if pkg1.T != pkg2.T {
panic("pkg1.T != pkg2.T")
}
if pkg1.U != pkg2.U {
panic("pkg1.U != pkg2.U")
}
if pkg1.V != pkg2.V {
panic("pkg1.V != pkg2.V")
}
if pkg1.W != pkg2.W {
panic("pkg1.W != pkg2.W")
}
}
// rundir
// Copyright 2012 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.
// Issue 4590: linker fails on multiple imports of
// an anonymous struct with methods.
package ignored
// errorcheck
// Copyright 2012 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 main
type bar struct {
x int
}
func main() {
var foo bar
_ = &foo{} // ERROR "is not a type|expected .;."
} // GCCGO_ERROR "expected declaration"
// compile
// Copyright 2012 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.
// Issue 4614: slicing of nil slices confuses the compiler
// with a uintptr(nil) node.
package p
import "unsafe"
var n int
var _ = []int(nil)[1:]
var _ = []int(nil)[n:]
var _ = uintptr(unsafe.Pointer(nil))
var _ = unsafe.Pointer(uintptr(0))
// run
// Copyright 2013 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 main
import (
"fmt"
"os"
"runtime"
"testing"
)
type T struct { int }
var globl *T
func F() {
t := &T{}
globl = t
}
func G() {
t := &T{}
_ = t
}
func main() {
nf := testing.AllocsPerRun(100, F)
ng := testing.AllocsPerRun(100, G)
if int(nf) != 1 {
fmt.Printf("AllocsPerRun(100, F) = %v, want 1\n", nf)
os.Exit(1)
}
if int(ng) != 0 && (runtime.Compiler != "gccgo" || int(ng) != 1) {
fmt.Printf("AllocsPerRun(100, G) = %v, want 0\n", ng)
os.Exit(1)
}
}
// run
// Copyright 2013 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.
// Issue 4620: map indexes are not evaluated before assignment of other elements
package main
import "fmt"
func main() {
m := map[int]int{0:1}
i := 0
i, m[i] = 1, 2
if m[0] != 2 {
fmt.Println(m)
panic("m[i] != 2")
}
}
// errorcheck
// Copyright 2013 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.
// Issue 4654.
// Check error for conversion and 'not used' in defer/go.
package p
import "unsafe"
func f() {
defer int(0) // ERROR "defer requires function call, not conversion|is not used"
go string([]byte("abc")) // ERROR "go requires function call, not conversion|is not used"
var c complex128
var f float64
var t struct {X int}
var x []int
defer append(x, 1) // ERROR "defer discards result of append|is not used"
defer cap(x) // ERROR "defer discards result of cap|is not used"
defer complex(1, 2) // ERROR "defer discards result of complex|is not used"
defer complex(f, 1) // ERROR "defer discards result of complex|is not used"
defer imag(1i) // ERROR "defer discards result of imag|is not used"
defer imag(c) // ERROR "defer discards result of imag|is not used"
defer len(x) // ERROR "defer discards result of len|is not used"
defer make([]int, 1) // ERROR "defer discards result of make|is not used"
defer make(chan bool) // ERROR "defer discards result of make|is not used"
defer make(map[string]int) // ERROR "defer discards result of make|is not used"
defer new(int) // ERROR "defer discards result of new|is not used"
defer real(1i) // ERROR "defer discards result of real|is not used"
defer real(c) // ERROR "defer discards result of real|is not used"
defer append(x, 1) // ERROR "defer discards result of append|is not used"
defer append(x, 1) // ERROR "defer discards result of append|is not used"
defer unsafe.Alignof(t.X) // ERROR "defer discards result of unsafe.Alignof|is not used"
defer unsafe.Offsetof(t.X) // ERROR "defer discards result of unsafe.Offsetof|is not used"
defer unsafe.Sizeof(t) // ERROR "defer discards result of unsafe.Sizeof|is not used"
defer copy(x, x) // ok
m := make(map[int]int)
defer delete(m, 1) // ok
defer panic(1) // ok
defer print(1) // ok
defer println(1) // ok
defer recover() // ok
int(0) // ERROR "int\(0\) evaluated but not used|is not used"
string([]byte("abc")) // ERROR "string\(.*\) evaluated but not used|is not used"
append(x, 1) // ERROR "not used"
cap(x) // ERROR "not used"
complex(1, 2) // ERROR "not used"
complex(f, 1) // ERROR "not used"
imag(1i) // ERROR "not used"
imag(c) // ERROR "not used"
len(x) // ERROR "not used"
make([]int, 1) // ERROR "not used"
make(chan bool) // ERROR "not used"
make(map[string]int) // ERROR "not used"
new(int) // ERROR "not used"
real(1i) // ERROR "not used"
real(c) // ERROR "not used"
append(x, 1) // ERROR "not used"
append(x, 1) // ERROR "not used"
unsafe.Alignof(t.X) // ERROR "not used"
unsafe.Offsetof(t.X) // ERROR "not used"
unsafe.Sizeof(t) // ERROR "not used"
}
// errorcheck
// Copyright 2013 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.
// Issue 4663.
// Make sure 'not used' message is placed correctly.
package main
func a(b int) int64 {
b // ERROR "not used"
return 0
}
// run
// Copyright 2013 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 main
import (
"fmt"
"os"
"testing"
)
var globl *int
func G() {
F()
}
func F() {
var x int
globl = &x
}
func main() {
nf := testing.AllocsPerRun(100, F)
ng := testing.AllocsPerRun(100, G)
if int(nf) != 1 {
fmt.Printf("AllocsPerRun(100, F) = %v, want 1\n", nf)
os.Exit(1)
}
if int(ng) != 1 {
fmt.Printf("AllocsPerRun(100, G) = %v, want 1\n", ng)
os.Exit(1)
}
}
// compile
// Copyright 2013 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.
// Caused gccgo to emit multiple definitions of the same symbol.
package p
type S1 struct{}
func (s *S1) M() {}
type S2 struct {
F struct{ *S1 }
}
func F() {
_ = struct{ *S1 }{}
}
// run
// Copyright 2013 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.
// Issue 4748.
// This program used to complain because inlining created two exit labels.
package main
func jump() {
goto exit
exit:
return
}
func main() {
jump()
jump()
}
// run
// Copyright 2013 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 main
func F(xi, yi interface{}) uint64 {
x, y := xi.(uint64), yi.(uint64)
return x &^ y
}
func G(xi, yi interface{}) uint64 {
return xi.(uint64) &^ yi.(uint64) // generates incorrect code
}
func main() {
var x, y uint64 = 0, 1 << 63
f := F(x, y)
g := G(x, y)
if f != 0 || g != 0 {
println("F", f, "G", g)
panic("bad")
}
}
// run
// Copyright 2013 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.
// issue 4785: used to fail to compile
package main
func t(x, y interface{}) interface{} {
return x.(float64) > y.(float64)
}
func main() {
v := t(1.0, 2.0)
if v != false {
panic("bad comparison")
}
}
// errorcheck
// Copyright 2013 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.
// Issue 4813: use of constant floats as indices.
package main
var A [3]int
var S []int
var T string
const (
i = 1
f = 2.0
f2 = 2.1
c = complex(2, 0)
c2 = complex(2, 1)
)
var (
vf = f
vc = c
)
var (
a1 = A[i]
a2 = A[f]
a3 = A[f2] // ERROR "truncated|must be integer"
a4 = A[c]
a5 = A[c2] // ERROR "truncated|must be integer"
a6 = A[vf] // ERROR "non-integer|must be integer"
a7 = A[vc] // ERROR "non-integer|must be integer"
s1 = S[i]
s2 = S[f]
s3 = S[f2] // ERROR "truncated|must be integer"
s4 = S[c]
s5 = S[c2] // ERROR "truncated|must be integer"
s6 = S[vf] // ERROR "non-integer|must be integer"
s7 = S[vc] // ERROR "non-integer|must be integer"
t1 = T[i]
t2 = T[f]
t3 = T[f2] // ERROR "truncated|must be integer"
t4 = T[c]
t5 = T[c2] // ERROR "truncated|must be integer"
t6 = T[vf] // ERROR "non-integer|must be integer"
t7 = T[vc] // ERROR "non-integer|must be integer"
)
package a
import (
"unsafe"
)
type Collection struct {
root unsafe.Pointer
}
type nodeLoc struct{}
type slice []int
type maptype map[int]int
func MakePrivateCollection() *Collection {
return &Collection{
root: unsafe.Pointer(&nodeLoc{}),
}
}
func MakePrivateCollection2() *Collection {
return &Collection{
root: unsafe.Pointer(&slice{}),
}
}
func MakePrivateCollection3() *Collection {
return &Collection{
root: unsafe.Pointer(&maptype{}),
}
}
package b
import "./a"
func F() {
a.MakePrivateCollection()
a.MakePrivateCollection2()
a.MakePrivateCollection3()
}
// compiledir
// Copyright 2013 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.
// Issue 4879: export data misses the '&' for some
// composite literals in inlined bodies.
package ignored
// errorcheck
// Copyright 2013 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.
// Issue 4909: compiler incorrectly accepts unsafe.Offsetof(t.x)
// where x is a field of an embedded pointer field.
package p
import (
"unsafe"
)
type T struct {
A int
*B
}
func (t T) Method() {}
type B struct {
X, Y int
}
var t T
var p *T
const N1 = unsafe.Offsetof(t.X) // ERROR "indirection"
const N2 = unsafe.Offsetof(p.X) // ERROR "indirection"
const N3 = unsafe.Offsetof(t.B.X) // valid
const N4 = unsafe.Offsetof(p.B.X) // valid
const N5 = unsafe.Offsetof(t.Method) // ERROR "method value"
const N6 = unsafe.Offsetof(p.Method) // ERROR "method value"
// errorcheckoutput
package main
import "fmt"
// We are going to define 256 types T(n),
// such that T(n) embeds T(2n) and *T(2n+1).
func main() {
fmt.Printf("// errorcheck\n\n")
fmt.Printf("package p\n\n")
fmt.Println(`import "unsafe"`)
// Dump types.
for n := 1; n < 256; n++ {
writeStruct(n)
}
// Dump leaves
for n := 256; n < 512; n++ {
fmt.Printf("type T%d int\n", n)
}
fmt.Printf("var t T1\n")
fmt.Printf("var p *T1\n")
// Simple selectors
for n := 2; n < 256; n++ {
writeDot(n)
}
// Double selectors
for n := 128; n < 256; n++ {
writeDot(n/16, n)
}
// Triple selectors
for n := 128; n < 256; n++ {
writeDot(n/64, n/8, n)
}
}
const structTpl = `
type T%d struct {
A%d int
T%d
*T%d
}
`
func writeStruct(n int) {
fmt.Printf(structTpl, n, n, 2*n, 2*n+1)
}
func writeDot(ns ...int) {
for _, root := range []string{"t", "p"} {
fmt.Printf("const _ = unsafe.Offsetof(%s", root)
for _, n := range ns {
fmt.Printf(".T%d", n)
}
// Does it involve an indirection?
nlast := ns[len(ns)-1]
nprev := 1
if len(ns) > 1 {
nprev = ns[len(ns)-2]
}
isIndirect := false
for n := nlast / 2; n > nprev; n /= 2 {
if n%2 == 1 {
isIndirect = true
break
}
}
fmt.Print(")")
if isIndirect {
fmt.Print(` // ERROR "indirection"`)
}
fmt.Print("\n")
}
}
// Copyright 2013 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 foo
type Op struct{}
// Copyright 2013 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 state
import "./foo"
func Public() {
var s Settings
s.op()
}
type State struct{}
func (s *State) x(*Settings) {}
type Settings struct{}
func (c *Settings) x() {
run([]foo.Op{{}})
}
func run([]foo.Op) {}
func (s *Settings) op() foo.Op {
return foo.Op{}
}
// Copyright 2013 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 state2
import "./state"
type Foo *state.State
// compiledir
// Copyright 2013 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.
// Issue 4932: regression in export of composite literals.
package ignored
// Copyright 2013 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 a
var global, global2 *int
type T struct {
Pointer *int
}
func dontinline() {}
func Store(t *T) {
global = t.Pointer
dontinline()
}
func Store2(t *T) {
global2 = t.Pointer
dontinline()
}
func Get() *int {
return global
}
// Copyright 2013 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 main
import "./a"
func F() {
// store 1 in a.global
x, y := 1, 2
t := a.T{Pointer: &x}
a.Store(&t)
_ = y
}
func G() {
// store 4 in a.global2
x, y := 3, 4
t := a.T{Pointer: &y}
a.Store2(&t)
_ = x
}
func main() {
F()
G()
p := a.Get()
n := *p
if n != 1 {
println(n, "!= 1")
panic("n != 1")
}
}
// rundir
// Copyright 2013 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.
// Issue 4964: exported escape analysis result is not enough
// for cross package analysis.
package ignored
// build
// Copyright 2013 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.
// Issue 5002: 8g produces invalid CMPL $0, $0.
// Used to fail at link time.
package main
func main() {
var y int64
if y%1 == 0 {
}
}
// run
// Copyright 2013 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.
// issue 5056: escape analysis not applied to wrapper functions
package main
type Foo int16
func (f Foo) Esc() *int{
x := int(f)
return &x
}
type iface interface {
Esc() *int
}
var bar, foobar *int
func main() {
var quux iface
var x Foo
quux = x
bar = quux.Esc()
foobar = quux.Esc()
if bar == foobar {
panic("bar == foobar")
}
}
// errorcheck
// Copyright 2013 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.
// issue 5089: gc allows methods on non-locals if symbol already exists
package p
import "bufio" // GCCGO_ERROR "previous"
func (b *bufio.Reader) Buffered() int { // ERROR "non-local|redefinition"
return -1
}
// Copyright 2013 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 a
var A = [2]string{"hello", "world"}
// Copyright 2013 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 main
import "./a"
var B = [2]string{"world", "hello"}
func main() {
if a.A[0] != B[1] {
panic("bad hello")
}
}
// rundir
// Copyright 2013 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.
// Issue 5105: linker segfaults on duplicate definition
// of a type..hash.* function.
package ignored
// Copyright 2013 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 bug
type Node interface {
Eval(s *Scene)
}
type plug struct {
node Node
}
type Scene struct {
changed map[plug]bool
}
// Copyright 2013 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 main
import _ "./bug"
func main() {
}
// compiledir
// Copyright 2013 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.
// Issue 5125: cyclic dependencies between types confuse
// the hashability test during import.
package ignored
// runoutput
// Copyright 2013 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.
// issue 5162: bad array equality when multiple comparisons
// happen in the same expression.
package main
import (
"fmt"
"strings"
)
const template = `
func CheckEqNNN_TTT() {
onesA := [NNN]ttt{ONES}
onesB := [NNN]ttt{ONES}
twos := [NNN]ttt{TWOS}
if onesA != onesB {
println("onesA != onesB in CheckEqNNN_TTT")
}
if onesA == twos {
println("onesA == twos in CheckEqNNN_TTT")
}
if onesB == twos {
println("onesB == twos in CheckEqNNN_TTT")
}
if s := fmt.Sprint(onesA == onesB, onesA != twos, onesB != twos); s != "true true true" {
println("fail in CheckEqNNN_TTT:", s)
}
}
func CheckEqNNN_TTTExtraVar() {
onesA := [NNN]ttt{ONES}
onesB := [NNN]ttt{ONES}
twos := [NNN]ttt{TWOS}
onesX := onesA
if onesA != onesB {
println("onesA != onesB in CheckEqNNN_TTTExtraVar")
}
if onesA == twos {
println("onesA == twos in CheckEqNNN_TTTExtraVar")
}
if onesB == twos {
println("onesB == twos in CheckEqNNN_TTTExtraVar")
}
if s := fmt.Sprint(onesA == onesB, onesA != twos, onesB != twos); s != "true true true" {
println("fail in CheckEqNNN_TTTExtraVar:", s)
}
if s := fmt.Sprint(onesB == onesX); s != "true" {
println("extra var fail in CheckEqNNN_TTTExtraVar")
}
}
`
func main() {
fmt.Print("// run\n\n")
fmt.Print("// THIS FILE IS AUTO-GENERATED\n\n")
fmt.Print("package main\n\n")
fmt.Println(`import "fmt"`)
types := []string{
"int", "int8", "int16", "int32", "int64",
"uint", "uint8", "uint16", "uint32", "uint64",
"float32", "float64"}
tocall := make([]string, 0, 32*len(types))
for i := 1; i <= 32; i++ {
for _, typ := range types {
src := template
src = strings.Replace(src, "NNN", fmt.Sprint(i), -1)
src = strings.Replace(src, "TTT", strings.Title(typ), -1)
src = strings.Replace(src, "ttt", typ, -1)
src = strings.Replace(src, "ONES", "1"+strings.Repeat(", 1", i-1), -1)
src = strings.Replace(src, "TWOS", "2"+strings.Repeat(", 2", i-1), -1)
fmt.Print(src)
tocall = append(tocall, fmt.Sprintf("CheckEq%d_%s", i, strings.Title(typ)))
}
}
fmt.Println("func main() {")
for _, fun := range tocall {
fmt.Printf("\t%s()\n", fun)
fmt.Printf("\t%sExtraVar()\n", fun)
}
fmt.Println("}")
}
// compile
// Copyright 2013 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.
// Issue 5231: method values lose their variadic property.
package p
type T int
func (t T) NotVariadic(s []int) int {
return int(t) + s[0]
}
func (t T) Variadic(s ...int) int {
return int(t) + s[0]
}
type I interface {
NotVariadic(s []int) int
Variadic(s ...int) int
}
func F() {
var t T
var p *T = &t
var i I = p
nv := t.NotVariadic
nv = p.NotVariadic
nv = i.NotVariadic
var s int = nv([]int{1, 2, 3})
v := t.Variadic
v = p.Variadic
v = i.Variadic
s = v(1, 2, 3)
var f1 func([]int) int = nv
var f2 func(...int) int = v
_, _, _ = f1, f2, s
}
// run
// Copyright 2013 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.
// Issue 5244: the init order computation uses the wrong
// order for top-level blank identifier assignments.
// The example used to panic because it tries calling a
// nil function instead of assigning to f before.
package main
var f = func() int { return 1 }
var _ = f() + g()
var g = func() int { return 2 }
func main() {}
// Copyright 2013 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 bug
type S struct {
F func()
}
type X interface {
Bar()
}
func Foo(x X) *S {
return &S{F: x.Bar}
}
// Copyright 2013 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 main
import "./bug"
type foo int
func (f *foo) Bar() {
}
func main() {
bug.Foo(new(foo))
}
// compiledir
// Copyright 2013 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.
// Issue 5259: Inlining of method value causes internal compiler error
package ignored
// Copyright 2013 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 a
const BOM = "\uFEFF"
// Copyright 2013 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 main
import "./a"
func main() {
_ = a.BOM
}
// rundir
// Copyright 2013 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.
// Issue 5260: Unicode BOM in exported string constant
// cannot be read back during package import.
package ignored
// Copyright 2013 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 pkg1
import (
"runtime"
)
type T2 *[]string
type Data struct {
T1 *[]T2
}
func CrashCall() (err error) {
var d Data
for count := 0; count < 10; count++ {
runtime.GC()
len := 2 // crash when >=2
x := make([]T2, len)
d = Data{T1: &x}
for j := 0; j < len; j++ {
y := make([]string, 1)
(*d.T1)[j] = &y
}
}
return nil
}
// Copyright 2013 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 main
import (
"./pkg1"
)
type message struct { // Presence of this creates a crash
data pkg1.Data
}
func main() {
pkg1.CrashCall()
}
// rundir
// Copyright 2013 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.
// Issue 5291: GC crash
package ignored
// Copyright 2013 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 a
type Foo interface {
Hi() string
}
func Test1() Foo { return make(tst1) }
type tst1 map[string]bool
func (r tst1) Hi() string { return "Hi!" }
func Test2() Foo { return make(tst2, 0) }
type tst2 []string
func (r tst2) Hi() string { return "Hi!" }
func Test3() Foo { return make(tst3) }
type tst3 chan string
func (r tst3) Hi() string { return "Hi!" }
// Copyright 2013 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 b
import "./a"
func main() {
a.Test1()
a.Test2()
a.Test3()
}
// compiledir
// Copyright 2013 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.
// Issue 5470: exported data for inlining may miss
// the type argument of make.
package ignored
// run
// Copyright 2013 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 main
import (
"runtime"
"sync"
"sync/atomic"
"time"
)
const N = 10
var count int64
func run() error {
f1 := func() {}
f2 := func() {
func() {
f1()
}()
}
runtime.SetFinalizer(&f1, func(f *func()) {
atomic.AddInt64(&count, -1)
})
go f2()
return nil
}
func main() {
// Does not work on 32-bits, or with gccgo, due to partially
// conservative GC.
// Try to enable when we have fully precise GC.
if runtime.GOARCH != "amd64" || runtime.Compiler == "gccgo" {
return
}
count = N
var wg sync.WaitGroup
wg.Add(N)
for i := 0; i < N; i++ {
go func() {
run()
wg.Done()
}()
}
wg.Wait()
for i := 0; i < 2*N; i++ {
time.Sleep(10 * time.Millisecond)
runtime.GC()
}
if count != 0 {
println(count, "out of", N, "finalizer are called")
panic("not all finalizers are called")
}
}
// run
// Copyright 2013 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.
// issue 5515: miscompilation doing inlining in generated method wrapper
package main
type T uint32
func main() {
b := make([]T, 8)
b[0] = 0xdeadbeef
rs := Slice(b)
sort(rs)
}
type Slice []T
func (s Slice) Swap(i, j int) {
tmp := s[i]
s[i] = s[j]
s[j] = tmp
}
type Interface interface {
Swap(i, j int)
}
func sort(data Interface) {
data.Swap(0, 4)
}
// run
// Copyright 2013 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.
// Issue 5607: generation of init() function incorrectly
// uses initializers of blank variables inside closures.
package main
var Test = func() {
var mymap = map[string]string{"a": "b"}
var innerTest = func() {
// Used to crash trying to compile this line as
// part of init() (funcdepth mismatch).
var _, x = mymap["a"]
println(x)
}
innerTest()
}
var Test2 = func() {
// The following initializer should not be part of init()
// The compiler used to generate a call to Panic() in init().
var _, x = Panic()
_ = x
}
func Panic() (int, int) {
panic("omg")
return 1, 2
}
func main() {}
package rethinkgo
type Session struct {
}
func (s *Session) Run(query Exp) *int { return nil }
type List []interface{}
type Exp struct {
args []interface{}
}
func (e Exp) UseOutdated(useOutdated bool) Exp {
return Exp{args: List{e, useOutdated}}
}
package x
import "./rethinkgo"
var S *rethinkgo.Session
// compiledir
// Copyright 2013 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.
// Issue 5614: exported data for inlining may miss
// named types when used in implicit conversion to
// their underlying type.
package ignored
// run
// Copyright 2013 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.
// issue 5753: bad typecheck info causes escape analysis to
// not run on method thunks.
package main
type Thing struct{}
func (t *Thing) broken(s string) []string {
foo := [1]string{s}
return foo[:]
}
func main() {
t := &Thing{}
f := t.broken
s := f("foo")
_ = f("bar")
if s[0] != "foo" {
panic(`s[0] != "foo"`)
}
}
// Copyright 2013 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 a
type I interface {
F()
}
type foo1 []byte
type foo2 []rune
type foo3 []uint8
type foo4 []int32
type foo5 string
type foo6 string
type foo7 string
type foo8 string
type foo9 string
func (f foo1) F() { return }
func (f foo2) F() { return }
func (f foo3) F() { return }
func (f foo4) F() { return }
func (f foo5) F() { return }
func (f foo6) F() { return }
func (f foo7) F() { return }
func (f foo8) F() { return }
func (f foo9) F() { return }
func Test1(s string) I { return foo1(s) }
func Test2(s string) I { return foo2(s) }
func Test3(s string) I { return foo3(s) }
func Test4(s string) I { return foo4(s) }
func Test5(s []byte) I { return foo5(s) }
func Test6(s []rune) I { return foo6(s) }
func Test7(s []uint8) I { return foo7(s) }
func Test8(s []int32) I { return foo8(s) }
func Test9(s int) I { return foo9(s) }
type bar map[int]int
func (b bar) F() { return }
func TestBar() I { return bar{1: 2} }
type baz int
func IsBaz(x interface{}) bool { _, ok := x.(baz); return ok }
type baz2 int
func IsBaz2(x interface{}) bool {
switch x.(type) {
case baz2:
return true
default:
return false
}
}
// Copyright 2013 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 main
import "./a"
func main() {
a.Test1("frumious")
a.Test2("frumious")
a.Test3("frumious")
a.Test4("frumious")
a.Test5(nil)
a.Test6(nil)
a.Test7(nil)
a.Test8(nil)
a.Test9(0)
a.TestBar()
a.IsBaz(nil)
}
// compiledir
// Copyright 2013 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.
// Issue 5755: exported data for inlining may miss
// named types when used in string conversions.
package ignored
// run
// Copyright 2013 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.
// issue 5809: 6g and 8g attempted to constant propagate indexed LEA
package main
import "fmt"
func main() {
const d16 = "0123456789ABCDEF"
k := 0x1234
var x [4]byte
x[0] = d16[k>>12&0xf]
x[1] = d16[k>>8&0xf]
x[2] = d16[k>>4&0xf]
x[3] = d16[k&0xf]
if x != [4]byte{'1','2','3','4'} {
fmt.Println(x)
panic("x != [4]byte{'1','2','3','4'}")
}
}
// run
// Copyright 2013 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.
// issue 5820: register clobber when clearfat and 64 bit arithmetic is interleaved.
package main
func main() {
array := make([][]int, 2)
index := uint64(1)
array[index] = nil
if array[1] != nil {
panic("array[1] != nil")
}
}
// build
// Copyright 2013 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.
// Issue 5841: 8g produces invalid CMPL $0, $0.
// Similar to issue 5002, used to fail at link time.
package main
func main() {
var y int
if y%1 == 0 {
}
}
// compile
// Copyright 2013 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.
// Used to leak registers on 8g.
package p
func f(x byte, y uint64) {
var r byte
switch y {
case 1:
r = x << y // '>>' triggers it too
case 2:
r = x << y
case 3:
r = x << y
case 4:
r = x << y
case 5:
r = x << y
case 6:
r = x << y
case 7:
r = x << y
case 8:
r = x << y
case 9:
r = x << y
case 10:
r = x << y
}
_ = r
}
...@@ -196,4 +196,8 @@ func main() { ...@@ -196,4 +196,8 @@ func main() {
if !close(-210.012e19, -210012, 1000, 19) { if !close(-210.012e19, -210012, 1000, 19) {
print("-210.012e19 is ", -210.012e19, "\n") print("-210.012e19 is ", -210.012e19, "\n")
} }
if bad {
panic("float_lit")
}
} }
...@@ -87,4 +87,7 @@ func main() { ...@@ -87,4 +87,7 @@ func main() {
println(t.name, "=", t.expr, "want", t.want) println(t.name, "=", t.expr, "want", t.want)
} }
} }
if bad {
panic("floatcmp failed")
}
} }
...@@ -14,6 +14,6 @@ func f1(a int) (int, float32) { ...@@ -14,6 +14,6 @@ func f1(a int) (int, float32) {
} }
func f2(a int) (a int, b float32) { // ERROR "redeclared|definition" func f2(a int) (a int, b float32) { // ERROR "duplicate argument a|definition"
return 8, 8.0 return 8, 8.0
} }
...@@ -17,7 +17,7 @@ func f() int { ...@@ -17,7 +17,7 @@ func f() int {
func g() int { func g() int {
if !calledf { if !calledf {
println("BUG: func7 - called g before f") panic("BUG: func7 - called g before f")
} }
return 0 return 0
} }
...@@ -28,4 +28,3 @@ func main() { ...@@ -28,4 +28,3 @@ func main() {
panic("wrong answer") panic("wrong answer")
} }
} }
...@@ -37,13 +37,13 @@ func y() string { ...@@ -37,13 +37,13 @@ func y() string {
func main() { func main() {
if f() == g() { if f() == g() {
println("wrong f,g order") panic("wrong f,g order")
} }
if x() == (y() == "abc") { if x() == (y() == "abc") {
panic("wrong compare") panic("wrong compare")
} }
if xy != "xy" { if xy != "xy" {
println("wrong x,y order") panic("wrong x,y order")
} }
} }
// errorcheck
// Copyright 2013 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 p
type T interface {
F1(i int) (i int) // ERROR "duplicate argument i|redefinition|previous"
F2(i, i int) // ERROR "duplicate argument i|redefinition|previous"
F3() (i, i int) // ERROR "duplicate argument i|redefinition|previous"
}
type T1 func(i, i int) // ERROR "duplicate argument i|redefinition|previous"
type T2 func(i int) (i int) // ERROR "duplicate argument i|redefinition|previous"
type T3 func() (i, i int) // ERROR "duplicate argument i|redefinition|previous"
type R struct{}
func (i *R) F1(i int) {} // ERROR "duplicate argument i|redefinition|previous"
func (i *R) F2() (i int) {return 0} // ERROR "duplicate argument i|redefinition|previous"
func (i *R) F3(j int) (j int) {return 0} // ERROR "duplicate argument j|redefinition|previous"
func F1(i, i int) {} // ERROR "duplicate argument i|redefinition|previous"
func F2(i int) (i int) {return 0} // ERROR "duplicate argument i|redefinition|previous"
func F3() (i, i int) {return 0, 0} // ERROR "duplicate argument i|redefinition|previous"
// errorcheck
// Copyright 2013 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 p
var T interface {
F1(i int) (i int) // ERROR "duplicate argument i|redefinition|previous"
F2(i, i int) // ERROR "duplicate argument i|redefinition|previous"
F3() (i, i int) // ERROR "duplicate argument i|redefinition|previous"
}
var T1 func(i, i int) // ERROR "duplicate argument i|redefinition|previous"
var T2 func(i int) (i int) // ERROR "duplicate argument i|redefinition|previous"
var T3 func() (i, i int) // ERROR "duplicate argument i|redefinition|previous"
...@@ -16,13 +16,9 @@ ...@@ -16,13 +16,9 @@
== fixedbugs/ == fixedbugs/
=========== fixedbugs/bug429.go =========== fixedbugs/bug429.go
throw: all goroutines are asleep - deadlock! fatal error: all goroutines are asleep - deadlock!
== bugs/ == bugs/
=========== bugs/bug395.go =========== bugs/bug395.go
bug395 is broken bug395 is broken
=========== bugs/bug434.go
bugs/bug434.dir/two.go:10: one.t.int undefined (cannot refer to unexported field or method one.int)
BUG:bug434
...@@ -12,5 +12,5 @@ import "time" ...@@ -12,5 +12,5 @@ import "time"
func main() { func main() {
go println(42, true, false, true, 1.5, "world", (chan int)(nil), []int(nil), (map[string]int)(nil), (func())(nil), byte(255)) go println(42, true, false, true, 1.5, "world", (chan int)(nil), []int(nil), (map[string]int)(nil), (func())(nil), byte(255))
time.Sleep(1e6) time.Sleep(100*time.Millisecond)
} }
// Copyright 2010 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.
// Various declarations of exported variables and functions.
package p
var C1 chan <- chan int = (chan<- (chan int))(nil)
var C2 chan (<- chan int) = (chan (<-chan int))(nil)
var C3 <- chan chan int = (<-chan (chan int))(nil)
var C4 chan chan <- int = (chan (chan<- int))(nil)
var C5 <- chan <- chan int = (<-chan (<-chan int))(nil)
var C6 chan <- <- chan int = (chan<- (<-chan int))(nil)
var C7 chan <- chan <- int = (chan<- (chan<- int))(nil)
var C8 <- chan <- chan chan int = (<-chan (<-chan (chan int)))(nil)
var C9 <- chan chan <- chan int = (<-chan (chan<- (chan int)))(nil)
var C10 chan <- <- chan chan int = (chan<- (<-chan (chan int)))(nil)
var C11 chan <- chan <- chan int = (chan<- (chan<- (chan int)))(nil)
var C12 chan chan <- <- chan int = (chan (chan<- (<-chan int)))(nil)
var C13 chan chan <- chan <- int = (chan (chan<- (chan<- int)))(nil)
var R1 chan<- (chan int) = (chan <- chan int)(nil)
var R3 <-chan (chan int) = (<- chan chan int)(nil)
var R4 chan (chan<- int) = (chan chan <- int)(nil)
var R5 <-chan (<-chan int) = (<- chan <- chan int)(nil)
var R6 chan<- (<-chan int) = (chan <- <- chan int)(nil)
var R7 chan<- (chan<- int) = (chan <- chan <- int)(nil)
var R8 <-chan (<-chan (chan int)) = (<- chan <- chan chan int)(nil)
var R9 <-chan (chan<- (chan int)) = (<- chan chan <- chan int)(nil)
var R10 chan<- (<-chan (chan int)) = (chan <- <- chan chan int)(nil)
var R11 chan<- (chan<- (chan int)) = (chan <- chan <- chan int)(nil)
var R12 chan (chan<- (<-chan int)) = (chan chan <- <- chan int)(nil)
var R13 chan (chan<- (chan<- int)) = (chan chan <- chan <- int)(nil)
var F1 func() func() int
func F2() func() func() int
func F3(func() func() int)
// $G $D/import2.go && $G $D/$F.go
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2010 The Go Authors. All rights reserved. // Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
......
// skip # used by import3 // compiledir
// Copyright 2010 The Go Authors. All rights reserved. // Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Various declarations of exported variables and functions. // Tests that export data does not corrupt type syntax.
// Imported by import3.go. package ignored
package p
var C1 chan <- chan int = (chan<- (chan int))(nil)
var C2 chan (<- chan int) = (chan (<-chan int))(nil)
var C3 <- chan chan int = (<-chan (chan int))(nil)
var C4 chan chan <- int = (chan (chan<- int))(nil)
var C5 <- chan <- chan int = (<-chan (<-chan int))(nil)
var C6 chan <- <- chan int = (chan<- (<-chan int))(nil)
var C7 chan <- chan <- int = (chan<- (chan<- int))(nil)
var C8 <- chan <- chan chan int = (<-chan (<-chan (chan int)))(nil)
var C9 <- chan chan <- chan int = (<-chan (chan<- (chan int)))(nil)
var C10 chan <- <- chan chan int = (chan<- (<-chan (chan int)))(nil)
var C11 chan <- chan <- chan int = (chan<- (chan<- (chan int)))(nil)
var C12 chan chan <- <- chan int = (chan (chan<- (<-chan int)))(nil)
var C13 chan chan <- chan <- int = (chan (chan<- (chan<- int)))(nil)
var R1 chan<- (chan int) = (chan <- chan int)(nil)
var R3 <-chan (chan int) = (<- chan chan int)(nil)
var R4 chan (chan<- int) = (chan chan <- int)(nil)
var R5 <-chan (<-chan int) = (<- chan <- chan int)(nil)
var R6 chan<- (<-chan int) = (chan <- <- chan int)(nil)
var R7 chan<- (chan<- int) = (chan <- chan <- int)(nil)
var R8 <-chan (<-chan (chan int)) = (<- chan <- chan chan int)(nil)
var R9 <-chan (chan<- (chan int)) = (<- chan chan <- chan int)(nil)
var R10 chan<- (<-chan (chan int)) = (chan <- <- chan chan int)(nil)
var R11 chan<- (chan<- (chan int)) = (chan <- chan <- chan int)(nil)
var R12 chan (chan<- (<-chan int)) = (chan chan <- <- chan int)(nil)
var R13 chan (chan<- (chan<- int)) = (chan chan <- chan <- int)(nil)
var F1 func() func() int
func F2() func() func() int
func F3(func() func() int)
// Copyright 2009 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 empty
import ( )
const ( )
var ( )
type ( )
// Copyright 2009 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.
// Verify that various kinds of "imported and not used"
// errors are caught by the compiler.
// Does not compile.
package main
// standard
import "fmt" // ERROR "imported and not used.*fmt"
// renamed
import X "math" // ERROR "imported and not used.*math"
// import dot
import . "bufio" // ERROR "imported and not used.*bufio"
// again, package without anything in it
import "./empty" // GC_ERROR "imported and not used.*empty"
import Z "./empty" // GC_ERROR "imported and not used.*empty"
import . "./empty" // ERROR "imported and not used.*empty"
// $G $D/empty.go && errchk $G $D/$F.go // errorcheckdir
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
...@@ -11,19 +8,4 @@ ...@@ -11,19 +8,4 @@
// errors are caught by the compiler. // errors are caught by the compiler.
// Does not compile. // Does not compile.
package main package ignored
// standard
import "fmt" // ERROR "imported and not used.*fmt"
// renamed
import X "math" // ERROR "imported and not used.*math"
// import dot
import . "bufio" // ERROR "imported and not used.*bufio"
// again, package without anything in it
import "./empty" // ERROR "imported and not used.*empty"
import Z "./empty" // ERROR "imported and not used.*empty"
import . "./empty" // ERROR "imported and not used.*empty"
...@@ -36,6 +36,8 @@ const ( ...@@ -36,6 +36,8 @@ const (
ci64big int64 = 1<<31 ci64big int64 = 1<<31
ci64bigger int64 = 1<<32 ci64bigger int64 = 1<<32
chuge = 1<<100 chuge = 1<<100
cfgood = 2.0
cfbad = 2.1
cnj = -2 cnj = -2
cni int = -3 cni int = -3
...@@ -46,6 +48,8 @@ const ( ...@@ -46,6 +48,8 @@ const (
cni64big int64 = -1<<31 cni64big int64 = -1<<31
cni64bigger int64 = -1<<32 cni64bigger int64 = -1<<32
cnhuge = -1<<100 cnhuge = -1<<100
cnfgood = -2.0
cnfbad = -2.1
) )
var j int = 100020 var j int = 100020
...@@ -57,6 +61,8 @@ var i64 int64 = 100023 ...@@ -57,6 +61,8 @@ var i64 int64 = 100023
var i64big int64 = 1<<31 var i64big int64 = 1<<31
var i64bigger int64 = 1<<32 var i64bigger int64 = 1<<32
var huge uint64 = 1<<64 - 1 var huge uint64 = 1<<64 - 1
var fgood float64 = 2.0
var fbad float64 = 2.1
var nj int = -10 var nj int = -10
var ni int = -11 var ni int = -11
...@@ -67,6 +73,8 @@ var ni64 int64 = -13 ...@@ -67,6 +73,8 @@ var ni64 int64 = -13
var ni64big int64 = -1<<31 var ni64big int64 = -1<<31
var ni64bigger int64 = -1<<32 var ni64bigger int64 = -1<<32
var nhuge int64 = -1<<63 var nhuge int64 = -1<<63
var nfgood float64 = -2.0
var nfbad float64 = -2.1
var si []int = make([]int, 10) var si []int = make([]int, 10)
var ai [10]int var ai [10]int
...@@ -156,7 +164,7 @@ func testExpr(b *bufio.Writer, expr string) { ...@@ -156,7 +164,7 @@ func testExpr(b *bufio.Writer, expr string) {
if pass == 0 { if pass == 0 {
fmt.Fprintf(b, "\ttest(func(){use(%s)}, %q)\n", expr, expr) fmt.Fprintf(b, "\ttest(func(){use(%s)}, %q)\n", expr, expr)
} else { } else {
fmt.Fprintf(b, "\tuse(%s) // ERROR \"index|overflow\"\n", expr) fmt.Fprintf(b, "\tuse(%s) // ERROR \"index|overflow|truncated|must be integer\"\n", expr)
} }
} }
...@@ -169,15 +177,15 @@ func main() { ...@@ -169,15 +177,15 @@ func main() {
fmt.Fprint(b, "// errorcheck\n\n") fmt.Fprint(b, "// errorcheck\n\n")
} }
fmt.Fprint(b, prolog) fmt.Fprint(b, prolog)
var choices = [][]string{ var choices = [][]string{
// Direct value, fetch from struct, fetch from struct pointer. // Direct value, fetch from struct, fetch from struct pointer.
// The last two cases get us to oindex_const_sudo in gsubr.c. // The last two cases get us to oindex_const_sudo in gsubr.c.
[]string{"", "t.", "pt."}, []string{"", "t.", "pt."},
// Array, pointer to array, slice. // Array, pointer to array, slice.
[]string{"a", "pa", "s"}, []string{"a", "pa", "s"},
// Element is int, element is quad (struct). // Element is int, element is quad (struct).
// This controls whether we end up in gsubr.c (i) or cgen.c (q). // This controls whether we end up in gsubr.c (i) or cgen.c (q).
[]string{"i", "q"}, []string{"i", "q"},
...@@ -192,9 +200,9 @@ func main() { ...@@ -192,9 +200,9 @@ func main() {
[]string{"", "n"}, []string{"", "n"},
// Size of index. // Size of index.
[]string{"j", "i", "i8", "i16", "i32", "i64", "i64big", "i64bigger", "huge"}, []string{"j", "i", "i8", "i16", "i32", "i64", "i64big", "i64bigger", "huge", "fgood", "fbad"},
} }
forall(choices, func(x []string) { forall(choices, func(x []string) {
p, a, e, big, c, n, i := x[0], x[1], x[2], x[3], x[4], x[5], x[6] p, a, e, big, c, n, i := x[0], x[1], x[2], x[3], x[4], x[5], x[6]
...@@ -206,7 +214,7 @@ func main() { ...@@ -206,7 +214,7 @@ func main() {
// negative constant // negative constant
// large constant // large constant
thisPass := 0 thisPass := 0
if c == "c" && (a == "a" || a == "pa" || n == "n" || i == "i64big" || i == "i64bigger" || i == "huge") { if c == "c" && (a == "a" || a == "pa" || n == "n" || i == "i64big" || i == "i64bigger" || i == "huge" || i == "fbad") {
if i == "huge" { if i == "huge" {
// Due to a detail of 6g's internals, // Due to a detail of 6g's internals,
// the huge constant errors happen in an // the huge constant errors happen in an
...@@ -223,27 +231,50 @@ func main() { ...@@ -223,27 +231,50 @@ func main() {
thisPass = 2 thisPass = 2
} }
} }
pae := p + a + e + big
cni := c + n + i
// If we're using the big-len data, positive int8 and int16 cannot overflow. // If we're using the big-len data, positive int8 and int16 cannot overflow.
if big == "b" && n == "" && (i == "i8" || i == "i16") { if big == "b" && n == "" && (i == "i8" || i == "i16") {
if pass == 0 {
fmt.Fprintf(b, "\tuse(%s[%s])\n", pae, cni)
fmt.Fprintf(b, "\tuse(%s[0:%s])\n", pae, cni)
fmt.Fprintf(b, "\tuse(%s[1:%s])\n", pae, cni)
fmt.Fprintf(b, "\tuse(%s[%s:])\n", pae, cni)
fmt.Fprintf(b, "\tuse(%s[%s:%s])\n", pae, cni, cni)
}
return
}
// Float variables cannot be used as indices.
if c == "" && (i == "fgood" || i == "fbad") {
return
}
// Integral float constat is ok.
if c == "c" && n == "" && i == "fgood" {
if pass == 0 {
fmt.Fprintf(b, "\tuse(%s[%s])\n", pae, cni)
fmt.Fprintf(b, "\tuse(%s[0:%s])\n", pae, cni)
fmt.Fprintf(b, "\tuse(%s[1:%s])\n", pae, cni)
fmt.Fprintf(b, "\tuse(%s[%s:])\n", pae, cni)
fmt.Fprintf(b, "\tuse(%s[%s:%s])\n", pae, cni, cni)
}
return return
} }
// Only print the test case if it is appropriate for this pass. // Only print the test case if it is appropriate for this pass.
if thisPass == pass { if thisPass == pass {
pae := p+a+e+big
cni := c+n+i
// Index operation // Index operation
testExpr(b, pae + "[" + cni + "]") testExpr(b, pae+"["+cni+"]")
// Slice operation. // Slice operation.
// Low index 0 is a special case in ggen.c // Low index 0 is a special case in ggen.c
// so test both 0 and 1. // so test both 0 and 1.
testExpr(b, pae + "[0:" + cni + "]") testExpr(b, pae+"[0:"+cni+"]")
testExpr(b, pae + "[1:" + cni + "]") testExpr(b, pae+"[1:"+cni+"]")
testExpr(b, pae + "[" + cni + ":]") testExpr(b, pae+"["+cni+":]")
testExpr(b, pae + "[" + cni + ":" + cni + "]") testExpr(b, pae+"["+cni+":"+cni+"]")
} }
}) })
...@@ -253,7 +284,7 @@ func main() { ...@@ -253,7 +284,7 @@ func main() {
func forall(choices [][]string, f func([]string)) { func forall(choices [][]string, f func([]string)) {
x := make([]string, len(choices)) x := make([]string, len(choices))
var recurse func(d int) var recurse func(d int)
recurse = func(d int) { recurse = func(d int) {
if d >= len(choices) { if d >= len(choices) {
...@@ -261,7 +292,7 @@ func forall(choices [][]string, f func([]string)) { ...@@ -261,7 +292,7 @@ func forall(choices [][]string, f func([]string)) {
return return
} }
for _, x[d] = range choices[d] { for _, x[d] = range choices[d] {
recurse(d+1) recurse(d + 1)
} }
} }
recurse(0) recurse(0)
......
...@@ -33,6 +33,7 @@ func init() { ...@@ -33,6 +33,7 @@ func init() {
sys1 := memstats.Sys sys1 := memstats.Sys
if sys1-sys > chunk*50 { if sys1-sys > chunk*50 {
println("allocated 1000 chunks of", chunk, "and used ", sys1-sys, "memory") println("allocated 1000 chunks of", chunk, "and used ", sys1-sys, "memory")
panic("init1")
} }
} }
......
...@@ -26,3 +26,15 @@ var a5 = []byte { x: 2 } // ERROR "index" ...@@ -26,3 +26,15 @@ var a5 = []byte { x: 2 } // ERROR "index"
var ok1 = S { } // should be ok var ok1 = S { } // should be ok
var ok2 = T { S: ok1 } // should be ok var ok2 = T { S: ok1 } // should be ok
// These keys can be computed at compile time but they are
// not constants as defined by the spec, so they do not trigger
// compile-time errors about duplicate key values.
// See issue 4555.
type Key struct {X, Y int}
var _ = map[Key]string{
Key{1,2}: "hello",
Key{1,2}: "world",
}
// skip # used by embed1.go
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
......
// Copyright 2009 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.
// Test that embedded interface types can have local methods.
package main
import "./embed0"
type T int
func (t T) m() {}
type I interface { m() }
type J interface { I }
type PI interface { p.I }
type PJ interface { p.J }
func main() {
var i I
var j J
var t T
i = t
j = t
_ = i
_ = j
i = j
_ = i
j = i
_ = j
var pi PI
var pj PJ
var pt p.T
pi = pt
pj = pt
_ = pi
_ = pj
pi = pj
_ = pi
pj = pi
_ = pj
}
// $G $D/embed0.go && $G $D/$F.go && $L $F.$A && ./$A.out // rundir
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
...@@ -9,40 +6,4 @@ ...@@ -9,40 +6,4 @@
// Test that embedded interface types can have local methods. // Test that embedded interface types can have local methods.
package main package ignored
import "./embed0"
type T int
func (t T) m() {}
type I interface { m() }
type J interface { I }
type PI interface { p.I }
type PJ interface { p.J }
func main() {
var i I
var j J
var t T
i = t
j = t
_ = i
_ = j
i = j
_ = i
j = i
_ = j
var pi PI
var pj PJ
var pt p.T
pi = pt
pj = pt
_ = pi
_ = pj
pi = pj
_ = pi
pj = pi
_ = pj
}
// skip # used by private.go
// Copyright 2011 The Go Authors. All rights reserved. // Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
......
// Copyright 2011 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.
// Test that unexported methods are not visible outside the package.
// Does not compile.
package main
import "./private1"
type Exported interface {
private()
}
type Implementation struct{}
func (p *Implementation) private() {}
func main() {
var x Exported
x = new(Implementation)
x.private()
var px p.Exported
px = p.X
px.private() // ERROR "private"
px = new(Implementation) // ERROR "private"
x = px // ERROR "private"
}
// $G $D/${F}1.go && errchk $G $D/$F.go // errorcheckdir
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2011 The Go Authors. All rights reserved. // Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
...@@ -10,29 +7,4 @@ ...@@ -10,29 +7,4 @@
// Test that unexported methods are not visible outside the package. // Test that unexported methods are not visible outside the package.
// Does not compile. // Does not compile.
package main package ignored
import "./private1"
type Exported interface {
private()
}
type Implementation struct{}
func (p *Implementation) private() {}
func main() {
var x Exported
x = new(Implementation)
x.private()
var px p.Exported
px = p.X
px.private() // ERROR "private"
px = new(Implementation) // ERROR "private"
x = px // ERROR "private"
}
// Copyright 2012 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.
// Mutually recursive type definitions imported and used by recursive1.go.
package p
type I1 interface {
F() I2
}
type I2 interface {
I1
}
// $G $D/recursive1.go && $G $D/$F.go
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2012 The Go Authors. All rights reserved. // Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
......
// skip # used by recursive2 // compiledir
// Copyright 2012 The Go Authors. All rights reserved. // Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
...@@ -6,12 +6,4 @@ ...@@ -6,12 +6,4 @@
// Mutually recursive type definitions imported and used by recursive1.go. // Mutually recursive type definitions imported and used by recursive1.go.
package p package ignored
type I1 interface {
F() I2
}
type I2 interface {
I1
}
...@@ -24,7 +24,6 @@ func equal(a, b float32) bool { ...@@ -24,7 +24,6 @@ func equal(a, b float32) bool {
return a == b return a == b
} }
func main() { func main() {
// bool // bool
var t bool = true var t bool = true
...@@ -225,6 +224,6 @@ func main() { ...@@ -225,6 +224,6 @@ func main() {
assert(sj0 == sj3, "sj3") assert(sj0 == sj3, "sj3")
if nbad > 0 { if nbad > 0 {
println() panic("literal failed")
} }
} }
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Test maps, almost exhaustively. // Test maps, almost exhaustively.
// NaN complexity test is in mapnan.go.
package main package main
...@@ -12,7 +13,6 @@ import ( ...@@ -12,7 +13,6 @@ import (
"fmt" "fmt"
"math" "math"
"strconv" "strconv"
"time"
) )
const count = 100 const count = 100
...@@ -41,7 +41,7 @@ func testbasic() { ...@@ -41,7 +41,7 @@ func testbasic() {
for i := 0; i < len(mlit); i++ { for i := 0; i < len(mlit); i++ {
s := string([]byte{byte(i) + '0'}) s := string([]byte{byte(i) + '0'})
if mlit[s] != i { if mlit[s] != i {
fmt.Printf("mlit[%s] = %d\n", s, mlit[s]) panic(fmt.Sprintf("mlit[%s] = %d\n", s, mlit[s]))
} }
} }
...@@ -102,46 +102,46 @@ func testbasic() { ...@@ -102,46 +102,46 @@ func testbasic() {
// test len // test len
if len(mib) != count { if len(mib) != count {
fmt.Printf("len(mib) = %d\n", len(mib)) panic(fmt.Sprintf("len(mib) = %d\n", len(mib)))
} }
if len(mii) != count { if len(mii) != count {
fmt.Printf("len(mii) = %d\n", len(mii)) panic(fmt.Sprintf("len(mii) = %d\n", len(mii)))
} }
if len(mfi) != count { if len(mfi) != count {
fmt.Printf("len(mfi) = %d\n", len(mfi)) panic(fmt.Sprintf("len(mfi) = %d\n", len(mfi)))
} }
if len(mif) != count { if len(mif) != count {
fmt.Printf("len(mif) = %d\n", len(mif)) panic(fmt.Sprintf("len(mif) = %d\n", len(mif)))
} }
if len(msi) != count { if len(msi) != count {
fmt.Printf("len(msi) = %d\n", len(msi)) panic(fmt.Sprintf("len(msi) = %d\n", len(msi)))
} }
if len(mis) != count { if len(mis) != count {
fmt.Printf("len(mis) = %d\n", len(mis)) panic(fmt.Sprintf("len(mis) = %d\n", len(mis)))
} }
if len(mss) != count { if len(mss) != count {
fmt.Printf("len(mss) = %d\n", len(mss)) panic(fmt.Sprintf("len(mss) = %d\n", len(mss)))
} }
if len(mspa) != count { if len(mspa) != count {
fmt.Printf("len(mspa) = %d\n", len(mspa)) panic(fmt.Sprintf("len(mspa) = %d\n", len(mspa)))
} }
if len(mipT) != count { if len(mipT) != count {
fmt.Printf("len(mipT) = %d\n", len(mipT)) panic(fmt.Sprintf("len(mipT) = %d\n", len(mipT)))
} }
if len(mpTi) != count { if len(mpTi) != count {
fmt.Printf("len(mpTi) = %d\n", len(mpTi)) panic(fmt.Sprintf("len(mpTi) = %d\n", len(mpTi)))
} }
// if len(mti) != count { // if len(mti) != count {
// fmt.Printf("len(mti) = %d\n", len(mti)) // panic(fmt.Sprintf("len(mti) = %d\n", len(mti)))
// } // }
if len(mipM) != count { if len(mipM) != count {
fmt.Printf("len(mipM) = %d\n", len(mipM)) panic(fmt.Sprintf("len(mipM) = %d\n", len(mipM)))
} }
// if len(mti) != count { // if len(mti) != count {
// fmt.Printf("len(mti) = %d\n", len(mti)) // panic(fmt.Sprintf("len(mti) = %d\n", len(mti)))
// } // }
if len(mit) != count { if len(mit) != count {
fmt.Printf("len(mit) = %d\n", len(mit)) panic(fmt.Sprintf("len(mit) = %d\n", len(mit)))
} }
// test construction directly // test construction directly
...@@ -151,48 +151,48 @@ func testbasic() { ...@@ -151,48 +151,48 @@ func testbasic() {
f := float32(i) f := float32(i)
// BUG m := M(i, i+1) // BUG m := M(i, i+1)
if mib[i] != (i != 0) { if mib[i] != (i != 0) {
fmt.Printf("mib[%d] = %t\n", i, mib[i]) panic(fmt.Sprintf("mib[%d] = %t\n", i, mib[i]))
} }
if mii[i] != 10*i { if mii[i] != 10*i {
fmt.Printf("mii[%d] = %d\n", i, mii[i]) panic(fmt.Sprintf("mii[%d] = %d\n", i, mii[i]))
} }
if mfi[f] != 10*i { if mfi[f] != 10*i {
fmt.Printf("mfi[%d] = %d\n", i, mfi[f]) panic(fmt.Sprintf("mfi[%d] = %d\n", i, mfi[f]))
} }
if mif[i] != 10.0*f { if mif[i] != 10.0*f {
fmt.Printf("mif[%d] = %g\n", i, mif[i]) panic(fmt.Sprintf("mif[%d] = %g\n", i, mif[i]))
} }
if mis[i] != s { if mis[i] != s {
fmt.Printf("mis[%d] = %s\n", i, mis[i]) panic(fmt.Sprintf("mis[%d] = %s\n", i, mis[i]))
} }
if msi[s] != i { if msi[s] != i {
fmt.Printf("msi[%s] = %d\n", s, msi[s]) panic(fmt.Sprintf("msi[%s] = %d\n", s, msi[s]))
} }
if mss[s] != s10 { if mss[s] != s10 {
fmt.Printf("mss[%s] = %g\n", s, mss[s]) panic(fmt.Sprintf("mss[%s] = %g\n", s, mss[s]))
} }
for j := 0; j < len(mspa[s]); j++ { for j := 0; j < len(mspa[s]); j++ {
if mspa[s][j] != s10 { if mspa[s][j] != s10 {
fmt.Printf("mspa[%s][%d] = %s\n", s, j, mspa[s][j]) panic(fmt.Sprintf("mspa[%s][%d] = %s\n", s, j, mspa[s][j]))
} }
} }
if mipT[i].i != int64(i) || mipT[i].f != f { if mipT[i].i != int64(i) || mipT[i].f != f {
fmt.Printf("mipT[%d] = %v\n", i, mipT[i]) panic(fmt.Sprintf("mipT[%d] = %v\n", i, mipT[i]))
} }
if mpTi[apT[i]] != i { if mpTi[apT[i]] != i {
fmt.Printf("mpTi[apT[%d]] = %d\n", i, mpTi[apT[i]]) panic(fmt.Sprintf("mpTi[apT[%d]] = %d\n", i, mpTi[apT[i]]))
} }
// if(mti[t] != i) { // if(mti[t] != i) {
// fmt.Printf("mti[%s] = %s\n", s, mti[t]) // panic(fmt.Sprintf("mti[%s] = %s\n", s, mti[t]))
// } // }
if mipM[i][i] != i+1 { if mipM[i][i] != i+1 {
fmt.Printf("mipM[%d][%d] = %d\n", i, i, mipM[i][i]) panic(fmt.Sprintf("mipM[%d][%d] = %d\n", i, i, mipM[i][i]))
} }
// if(mti[t] != i) { // if(mti[t] != i) {
// fmt.Printf("mti[%v] = %d\n", t, mti[t]) // panic(fmt.Sprintf("mti[%v] = %d\n", t, mti[t]))
// } // }
if mit[i].i != int64(i) || mit[i].f != f { if mit[i].i != int64(i) || mit[i].f != f {
fmt.Printf("mit[%d] = {%d %g}\n", i, mit[i].i, mit[i].f) panic(fmt.Sprintf("mit[%d] = {%d %g}\n", i, mit[i].i, mit[i].f))
} }
} }
...@@ -204,131 +204,131 @@ func testbasic() { ...@@ -204,131 +204,131 @@ func testbasic() {
{ {
_, b := mib[i] _, b := mib[i]
if !b { if !b {
fmt.Printf("tuple existence decl: mib[%d]\n", i) panic(fmt.Sprintf("tuple existence decl: mib[%d]\n", i))
} }
_, b = mib[i] _, b = mib[i]
if !b { if !b {
fmt.Printf("tuple existence assign: mib[%d]\n", i) panic(fmt.Sprintf("tuple existence assign: mib[%d]\n", i))
} }
} }
{ {
_, b := mii[i] _, b := mii[i]
if !b { if !b {
fmt.Printf("tuple existence decl: mii[%d]\n", i) panic(fmt.Sprintf("tuple existence decl: mii[%d]\n", i))
} }
_, b = mii[i] _, b = mii[i]
if !b { if !b {
fmt.Printf("tuple existence assign: mii[%d]\n", i) panic(fmt.Sprintf("tuple existence assign: mii[%d]\n", i))
} }
} }
{ {
_, b := mfi[f] _, b := mfi[f]
if !b { if !b {
fmt.Printf("tuple existence decl: mfi[%d]\n", i) panic(fmt.Sprintf("tuple existence decl: mfi[%d]\n", i))
} }
_, b = mfi[f] _, b = mfi[f]
if !b { if !b {
fmt.Printf("tuple existence assign: mfi[%d]\n", i) panic(fmt.Sprintf("tuple existence assign: mfi[%d]\n", i))
} }
} }
{ {
_, b := mif[i] _, b := mif[i]
if !b { if !b {
fmt.Printf("tuple existence decl: mif[%d]\n", i) panic(fmt.Sprintf("tuple existence decl: mif[%d]\n", i))
} }
_, b = mif[i] _, b = mif[i]
if !b { if !b {
fmt.Printf("tuple existence assign: mif[%d]\n", i) panic(fmt.Sprintf("tuple existence assign: mif[%d]\n", i))
} }
} }
{ {
_, b := mis[i] _, b := mis[i]
if !b { if !b {
fmt.Printf("tuple existence decl: mis[%d]\n", i) panic(fmt.Sprintf("tuple existence decl: mis[%d]\n", i))
} }
_, b = mis[i] _, b = mis[i]
if !b { if !b {
fmt.Printf("tuple existence assign: mis[%d]\n", i) panic(fmt.Sprintf("tuple existence assign: mis[%d]\n", i))
} }
} }
{ {
_, b := msi[s] _, b := msi[s]
if !b { if !b {
fmt.Printf("tuple existence decl: msi[%d]\n", i) panic(fmt.Sprintf("tuple existence decl: msi[%d]\n", i))
} }
_, b = msi[s] _, b = msi[s]
if !b { if !b {
fmt.Printf("tuple existence assign: msi[%d]\n", i) panic(fmt.Sprintf("tuple existence assign: msi[%d]\n", i))
} }
} }
{ {
_, b := mss[s] _, b := mss[s]
if !b { if !b {
fmt.Printf("tuple existence decl: mss[%d]\n", i) panic(fmt.Sprintf("tuple existence decl: mss[%d]\n", i))
} }
_, b = mss[s] _, b = mss[s]
if !b { if !b {
fmt.Printf("tuple existence assign: mss[%d]\n", i) panic(fmt.Sprintf("tuple existence assign: mss[%d]\n", i))
} }
} }
{ {
_, b := mspa[s] _, b := mspa[s]
if !b { if !b {
fmt.Printf("tuple existence decl: mspa[%d]\n", i) panic(fmt.Sprintf("tuple existence decl: mspa[%d]\n", i))
} }
_, b = mspa[s] _, b = mspa[s]
if !b { if !b {
fmt.Printf("tuple existence assign: mspa[%d]\n", i) panic(fmt.Sprintf("tuple existence assign: mspa[%d]\n", i))
} }
} }
{ {
_, b := mipT[i] _, b := mipT[i]
if !b { if !b {
fmt.Printf("tuple existence decl: mipT[%d]\n", i) panic(fmt.Sprintf("tuple existence decl: mipT[%d]\n", i))
} }
_, b = mipT[i] _, b = mipT[i]
if !b { if !b {
fmt.Printf("tuple existence assign: mipT[%d]\n", i) panic(fmt.Sprintf("tuple existence assign: mipT[%d]\n", i))
} }
} }
{ {
_, b := mpTi[apT[i]] _, b := mpTi[apT[i]]
if !b { if !b {
fmt.Printf("tuple existence decl: mpTi[apT[%d]]\n", i) panic(fmt.Sprintf("tuple existence decl: mpTi[apT[%d]]\n", i))
} }
_, b = mpTi[apT[i]] _, b = mpTi[apT[i]]
if !b { if !b {
fmt.Printf("tuple existence assign: mpTi[apT[%d]]\n", i) panic(fmt.Sprintf("tuple existence assign: mpTi[apT[%d]]\n", i))
} }
} }
{ {
_, b := mipM[i] _, b := mipM[i]
if !b { if !b {
fmt.Printf("tuple existence decl: mipM[%d]\n", i) panic(fmt.Sprintf("tuple existence decl: mipM[%d]\n", i))
} }
_, b = mipM[i] _, b = mipM[i]
if !b { if !b {
fmt.Printf("tuple existence assign: mipM[%d]\n", i) panic(fmt.Sprintf("tuple existence assign: mipM[%d]\n", i))
} }
} }
{ {
_, b := mit[i] _, b := mit[i]
if !b { if !b {
fmt.Printf("tuple existence decl: mit[%d]\n", i) panic(fmt.Sprintf("tuple existence decl: mit[%d]\n", i))
} }
_, b = mit[i] _, b = mit[i]
if !b { if !b {
fmt.Printf("tuple existence assign: mit[%d]\n", i) panic(fmt.Sprintf("tuple existence assign: mit[%d]\n", i))
} }
} }
// { // {
// _, b := mti[t] // _, b := mti[t]
// if !b { // if !b {
// fmt.Printf("tuple existence decl: mti[%d]\n", i) // panic(fmt.Sprintf("tuple existence decl: mti[%d]\n", i))
// } // }
// _, b = mti[t] // _, b = mti[t]
// if !b { // if !b {
// fmt.Printf("tuple existence assign: mti[%d]\n", i) // panic(fmt.Sprintf("tuple existence assign: mti[%d]\n", i))
// } // }
// } // }
} }
...@@ -341,131 +341,131 @@ func testbasic() { ...@@ -341,131 +341,131 @@ func testbasic() {
{ {
_, b := mib[i] _, b := mib[i]
if b { if b {
fmt.Printf("tuple nonexistence decl: mib[%d]", i) panic(fmt.Sprintf("tuple nonexistence decl: mib[%d]", i))
} }
_, b = mib[i] _, b = mib[i]
if b { if b {
fmt.Printf("tuple nonexistence assign: mib[%d]", i) panic(fmt.Sprintf("tuple nonexistence assign: mib[%d]", i))
} }
} }
{ {
_, b := mii[i] _, b := mii[i]
if b { if b {
fmt.Printf("tuple nonexistence decl: mii[%d]", i) panic(fmt.Sprintf("tuple nonexistence decl: mii[%d]", i))
} }
_, b = mii[i] _, b = mii[i]
if b { if b {
fmt.Printf("tuple nonexistence assign: mii[%d]", i) panic(fmt.Sprintf("tuple nonexistence assign: mii[%d]", i))
} }
} }
{ {
_, b := mfi[f] _, b := mfi[f]
if b { if b {
fmt.Printf("tuple nonexistence decl: mfi[%d]", i) panic(fmt.Sprintf("tuple nonexistence decl: mfi[%d]", i))
} }
_, b = mfi[f] _, b = mfi[f]
if b { if b {
fmt.Printf("tuple nonexistence assign: mfi[%d]", i) panic(fmt.Sprintf("tuple nonexistence assign: mfi[%d]", i))
} }
} }
{ {
_, b := mif[i] _, b := mif[i]
if b { if b {
fmt.Printf("tuple nonexistence decl: mif[%d]", i) panic(fmt.Sprintf("tuple nonexistence decl: mif[%d]", i))
} }
_, b = mif[i] _, b = mif[i]
if b { if b {
fmt.Printf("tuple nonexistence assign: mif[%d]", i) panic(fmt.Sprintf("tuple nonexistence assign: mif[%d]", i))
} }
} }
{ {
_, b := mis[i] _, b := mis[i]
if b { if b {
fmt.Printf("tuple nonexistence decl: mis[%d]", i) panic(fmt.Sprintf("tuple nonexistence decl: mis[%d]", i))
} }
_, b = mis[i] _, b = mis[i]
if b { if b {
fmt.Printf("tuple nonexistence assign: mis[%d]", i) panic(fmt.Sprintf("tuple nonexistence assign: mis[%d]", i))
} }
} }
{ {
_, b := msi[s] _, b := msi[s]
if b { if b {
fmt.Printf("tuple nonexistence decl: msi[%d]", i) panic(fmt.Sprintf("tuple nonexistence decl: msi[%d]", i))
} }
_, b = msi[s] _, b = msi[s]
if b { if b {
fmt.Printf("tuple nonexistence assign: msi[%d]", i) panic(fmt.Sprintf("tuple nonexistence assign: msi[%d]", i))
} }
} }
{ {
_, b := mss[s] _, b := mss[s]
if b { if b {
fmt.Printf("tuple nonexistence decl: mss[%d]", i) panic(fmt.Sprintf("tuple nonexistence decl: mss[%d]", i))
} }
_, b = mss[s] _, b = mss[s]
if b { if b {
fmt.Printf("tuple nonexistence assign: mss[%d]", i) panic(fmt.Sprintf("tuple nonexistence assign: mss[%d]", i))
} }
} }
{ {
_, b := mspa[s] _, b := mspa[s]
if b { if b {
fmt.Printf("tuple nonexistence decl: mspa[%d]", i) panic(fmt.Sprintf("tuple nonexistence decl: mspa[%d]", i))
} }
_, b = mspa[s] _, b = mspa[s]
if b { if b {
fmt.Printf("tuple nonexistence assign: mspa[%d]", i) panic(fmt.Sprintf("tuple nonexistence assign: mspa[%d]", i))
} }
} }
{ {
_, b := mipT[i] _, b := mipT[i]
if b { if b {
fmt.Printf("tuple nonexistence decl: mipT[%d]", i) panic(fmt.Sprintf("tuple nonexistence decl: mipT[%d]", i))
} }
_, b = mipT[i] _, b = mipT[i]
if b { if b {
fmt.Printf("tuple nonexistence assign: mipT[%d]", i) panic(fmt.Sprintf("tuple nonexistence assign: mipT[%d]", i))
} }
} }
{ {
_, b := mpTi[apT[i]] _, b := mpTi[apT[i]]
if b { if b {
fmt.Printf("tuple nonexistence decl: mpTi[apt[%d]]", i) panic(fmt.Sprintf("tuple nonexistence decl: mpTi[apt[%d]]", i))
} }
_, b = mpTi[apT[i]] _, b = mpTi[apT[i]]
if b { if b {
fmt.Printf("tuple nonexistence assign: mpTi[apT[%d]]", i) panic(fmt.Sprintf("tuple nonexistence assign: mpTi[apT[%d]]", i))
} }
} }
{ {
_, b := mipM[i] _, b := mipM[i]
if b { if b {
fmt.Printf("tuple nonexistence decl: mipM[%d]", i) panic(fmt.Sprintf("tuple nonexistence decl: mipM[%d]", i))
} }
_, b = mipM[i] _, b = mipM[i]
if b { if b {
fmt.Printf("tuple nonexistence assign: mipM[%d]", i) panic(fmt.Sprintf("tuple nonexistence assign: mipM[%d]", i))
} }
} }
// { // {
// _, b := mti[t] // _, b := mti[t]
// if b { // if b {
// fmt.Printf("tuple nonexistence decl: mti[%d]", i) // panic(fmt.Sprintf("tuple nonexistence decl: mti[%d]", i))
// } // }
// _, b = mti[t] // _, b = mti[t]
// if b { // if b {
// fmt.Printf("tuple nonexistence assign: mti[%d]", i) // panic(fmt.Sprintf("tuple nonexistence assign: mti[%d]", i))
// } // }
// } // }
{ {
_, b := mit[i] _, b := mit[i]
if b { if b {
fmt.Printf("tuple nonexistence decl: mit[%d]", i) panic(fmt.Sprintf("tuple nonexistence decl: mit[%d]", i))
} }
_, b = mit[i] _, b = mit[i]
if b { if b {
fmt.Printf("tuple nonexistence assign: mit[%d]", i) panic(fmt.Sprintf("tuple nonexistence assign: mit[%d]", i))
} }
} }
} }
...@@ -475,21 +475,25 @@ func testbasic() { ...@@ -475,21 +475,25 @@ func testbasic() {
s := strconv.Itoa(i) s := strconv.Itoa(i)
mspa[s][i%2] = "deleted" mspa[s][i%2] = "deleted"
if mspa[s][i%2] != "deleted" { if mspa[s][i%2] != "deleted" {
fmt.Printf("update mspa[%s][%d] = %s\n", s, i%2, mspa[s][i%2]) panic(fmt.Sprintf("update mspa[%s][%d] = %s\n", s, i%2, mspa[s][i%2]))
} }
mipT[i].i += 1 mipT[i].i += 1
if mipT[i].i != int64(i)+1 { if mipT[i].i != int64(i)+1 {
fmt.Printf("update mipT[%d].i = %d\n", i, mipT[i].i) panic(fmt.Sprintf("update mipT[%d].i = %d\n", i, mipT[i].i))
} }
mipT[i].f = float32(i + 1) mipT[i].f = float32(i + 1)
if mipT[i].f != float32(i+1) { if mipT[i].f != float32(i+1) {
fmt.Printf("update mipT[%d].f = %g\n", i, mipT[i].f) panic(fmt.Sprintf("update mipT[%d].f = %g\n", i, mipT[i].f))
} }
mipM[i][i]++ mipM[i][i]++
if mipM[i][i] != (i+1)+1 { if mipM[i][i] != (i+1)+1 {
fmt.Printf("update mipM[%d][%d] = %d\n", i, i, mipM[i][i]) panic(fmt.Sprintf("update mipM[%d][%d] = %d\n", i, i, mipM[i][i]))
} }
} }
...@@ -519,29 +523,29 @@ func testfloat() { ...@@ -519,29 +523,29 @@ func testfloat() {
nanb: "NaN", nanb: "NaN",
} }
if m[pz] != "+0" { if m[pz] != "+0" {
fmt.Println("float32 map cannot read back m[+0]:", m[pz]) panic(fmt.Sprintln("float32 map cannot read back m[+0]:", m[pz]))
} }
if m[nz] != "+0" { if m[nz] != "+0" {
fmt.Println("float32 map does not treat", pz, "and", nz, "as equal for read") fmt.Sprintln("float32 map does not treat", pz, "and", nz, "as equal for read")
fmt.Println("float32 map does not treat -0 and +0 as equal for read") panic(fmt.Sprintln("float32 map does not treat -0 and +0 as equal for read"))
} }
m[nz] = "-0" m[nz] = "-0"
if m[pz] != "-0" { if m[pz] != "-0" {
fmt.Println("float32 map does not treat -0 and +0 as equal for write") panic(fmt.Sprintln("float32 map does not treat -0 and +0 as equal for write"))
} }
if _, ok := m[nana]; ok { if _, ok := m[nana]; ok {
fmt.Println("float32 map allows NaN lookup (a)") panic(fmt.Sprintln("float32 map allows NaN lookup (a)"))
} }
if _, ok := m[nanb]; ok { if _, ok := m[nanb]; ok {
fmt.Println("float32 map allows NaN lookup (b)") panic(fmt.Sprintln("float32 map allows NaN lookup (b)"))
} }
if len(m) != 3 { if len(m) != 3 {
fmt.Println("float32 map should have 3 entries:", m) panic(fmt.Sprintln("float32 map should have 3 entries:", m))
} }
m[nana] = "NaN" m[nana] = "NaN"
m[nanb] = "NaN" m[nanb] = "NaN"
if len(m) != 5 { if len(m) != 5 {
fmt.Println("float32 map should have 5 entries:", m) panic(fmt.Sprintln("float32 map should have 5 entries:", m))
} }
} }
...@@ -559,25 +563,25 @@ func testfloat() { ...@@ -559,25 +563,25 @@ func testfloat() {
nanb: "NaN", nanb: "NaN",
} }
if m[nz] != "+0" { if m[nz] != "+0" {
fmt.Println("float64 map does not treat -0 and +0 as equal for read") panic(fmt.Sprintln("float64 map does not treat -0 and +0 as equal for read"))
} }
m[nz] = "-0" m[nz] = "-0"
if m[pz] != "-0" { if m[pz] != "-0" {
fmt.Println("float64 map does not treat -0 and +0 as equal for write") panic(fmt.Sprintln("float64 map does not treat -0 and +0 as equal for write"))
} }
if _, ok := m[nana]; ok { if _, ok := m[nana]; ok {
fmt.Println("float64 map allows NaN lookup (a)") panic(fmt.Sprintln("float64 map allows NaN lookup (a)"))
} }
if _, ok := m[nanb]; ok { if _, ok := m[nanb]; ok {
fmt.Println("float64 map allows NaN lookup (b)") panic(fmt.Sprintln("float64 map allows NaN lookup (b)"))
} }
if len(m) != 3 { if len(m) != 3 {
fmt.Println("float64 map should have 3 entries:", m) panic(fmt.Sprintln("float64 map should have 3 entries:", m))
} }
m[nana] = "NaN" m[nana] = "NaN"
m[nanb] = "NaN" m[nanb] = "NaN"
if len(m) != 5 { if len(m) != 5 {
fmt.Println("float64 map should have 5 entries:", m) panic(fmt.Sprintln("float64 map should have 5 entries:", m))
} }
} }
...@@ -595,25 +599,25 @@ func testfloat() { ...@@ -595,25 +599,25 @@ func testfloat() {
nanb: "NaN", nanb: "NaN",
} }
if m[nz] != "+0" { if m[nz] != "+0" {
fmt.Println("complex64 map does not treat -0 and +0 as equal for read") panic(fmt.Sprintln("complex64 map does not treat -0 and +0 as equal for read"))
} }
m[nz] = "-0" m[nz] = "-0"
if m[pz] != "-0" { if m[pz] != "-0" {
fmt.Println("complex64 map does not treat -0 and +0 as equal for write") panic(fmt.Sprintln("complex64 map does not treat -0 and +0 as equal for write"))
} }
if _, ok := m[nana]; ok { if _, ok := m[nana]; ok {
fmt.Println("complex64 map allows NaN lookup (a)") panic(fmt.Sprintln("complex64 map allows NaN lookup (a)"))
} }
if _, ok := m[nanb]; ok { if _, ok := m[nanb]; ok {
fmt.Println("complex64 map allows NaN lookup (b)") panic(fmt.Sprintln("complex64 map allows NaN lookup (b)"))
} }
if len(m) != 3 { if len(m) != 3 {
fmt.Println("complex64 map should have 3 entries:", m) panic(fmt.Sprintln("complex64 map should have 3 entries:", m))
} }
m[nana] = "NaN" m[nana] = "NaN"
m[nanb] = "NaN" m[nanb] = "NaN"
if len(m) != 5 { if len(m) != 5 {
fmt.Println("complex64 map should have 5 entries:", m) panic(fmt.Sprintln("complex64 map should have 5 entries:", m))
} }
} }
...@@ -631,63 +635,50 @@ func testfloat() { ...@@ -631,63 +635,50 @@ func testfloat() {
nanb: "NaN", nanb: "NaN",
} }
if m[nz] != "+0" { if m[nz] != "+0" {
fmt.Println("complex128 map does not treat -0 and +0 as equal for read") panic(fmt.Sprintln("complex128 map does not treat -0 and +0 as equal for read"))
} }
m[nz] = "-0" m[nz] = "-0"
if m[pz] != "-0" { if m[pz] != "-0" {
fmt.Println("complex128 map does not treat -0 and +0 as equal for write") panic(fmt.Sprintln("complex128 map does not treat -0 and +0 as equal for write"))
} }
if _, ok := m[nana]; ok { if _, ok := m[nana]; ok {
fmt.Println("complex128 map allows NaN lookup (a)") panic(fmt.Sprintln("complex128 map allows NaN lookup (a)"))
} }
if _, ok := m[nanb]; ok { if _, ok := m[nanb]; ok {
fmt.Println("complex128 map allows NaN lookup (b)") panic(fmt.Sprintln("complex128 map allows NaN lookup (b)"))
} }
if len(m) != 3 { if len(m) != 3 {
fmt.Println("complex128 map should have 3 entries:", m) panic(fmt.Sprintln("complex128 map should have 3 entries:", m))
} }
m[nana] = "NaN" m[nana] = "NaN"
m[nanb] = "NaN" m[nanb] = "NaN"
if len(m) != 5 { if len(m) != 5 {
fmt.Println("complex128 map should have 5 entries:", m) panic(fmt.Sprintln("complex128 map should have 5 entries:", m))
} }
} }
} }
func testnan() { func testnan() {
// Test that NaNs in maps don't go quadratic. n := 500
t := func(n int) time.Duration { m := map[float64]int{}
t0 := time.Now() nan := math.NaN()
m := map[float64]int{} for i := 0; i < n; i++ {
nan := math.NaN() m[nan] = 1
for i := 0; i < n; i++ {
m[nan] = 1
}
if len(m) != n {
panic("wrong size map after nan insertion")
}
return time.Since(t0)
} }
if len(m) != n {
// Depending on the machine and OS, this test might be too fast panic("wrong size map after nan insertion")
// to measure with accurate enough granularity. On failure, }
// make it run longer, hoping that the timing granularity iters := 0
// is eventually sufficient. for k, v := range m {
iters++
n := 30000 // 0.02 seconds on a MacBook Air if !math.IsNaN(k) {
fails := 0 panic("not NaN")
for { }
t1 := t(n) if v != 1 {
t2 := t(2 * n) panic("wrong value")
// should be 2x (linear); allow up to 3x }
if t2 < 3*t1 { }
return if iters != n {
} panic("wrong number of nan range iters")
fails++
if fails == 4 {
fmt.Printf("too slow: %d inserts: %v; %d inserts: %v\n", n, t1, 2*n, t2)
return
}
n *= 2
} }
} }
// +build darwin linux
// run
// Copyright 2013 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.
// Test that NaNs in maps don't go quadratic.
package main
import (
"fmt"
"math"
"time"
"syscall"
)
func main() {
// Test that NaNs in maps don't go quadratic.
t := func(n int) time.Duration {
var u0 syscall.Rusage
if err := syscall.Getrusage(0, &u0); err != nil {
panic(err)
}
m := map[float64]int{}
nan := math.NaN()
for i := 0; i < n; i++ {
m[nan] = 1
}
if len(m) != n {
panic("wrong size map after nan insertion")
}
var u1 syscall.Rusage
if err := syscall.Getrusage(0, &u1); err != nil {
panic(err)
}
return time.Duration(u1.Utime.Nano() - u0.Utime.Nano())
}
// Depending on the machine and OS, this test might be too fast
// to measure with accurate enough granularity. On failure,
// make it run longer, hoping that the timing granularity
// is eventually sufficient.
n := 30000 // ~8ms user time on a Mid 2011 MacBook Air (1.8 GHz Core i7)
fails := 0
for {
t1 := t(n)
t2 := t(2 * n)
// should be 2x (linear); allow up to 3x
if t2 < 3*t1 {
return
}
fails++
if fails == 6 {
panic(fmt.Sprintf("too slow: %d inserts: %v; %d inserts: %v\n", n, t1, 2*n, t2))
}
if fails < 4 {
n *= 2
}
}
}
...@@ -128,13 +128,13 @@ func main() { ...@@ -128,13 +128,13 @@ func main() {
panic("fail") panic("fail")
} }
var zs struct { S } var zs struct{ S }
var zps struct { *S1 } var zps struct{ *S1 }
var zi struct { I } var zi struct{ I }
var zpi struct { *I1 } var zpi struct{ *I1 }
var zpt struct { *T1 } var zpt struct{ *T1 }
var zt struct { T } var zt struct{ T }
var zv struct { Val } var zv struct{ Val }
if zs.val() != 1 { if zs.val() != 1 {
println("zs.val:", zs.val()) println("zs.val:", zs.val())
...@@ -247,4 +247,61 @@ func main() { ...@@ -247,4 +247,61 @@ func main() {
println("zv.val():", zv.val()) println("zv.val():", zv.val())
panic("fail") panic("fail")
} }
promotion()
}
type A struct{ B }
type B struct {
C
*D
}
type C int
func (C) f() {} // value receiver, direct field of A
func (*C) g() {} // pointer receiver
type D int
func (D) h() {} // value receiver, indirect field of A
func (*D) i() {} // pointer receiver
func expectPanic() {
if r := recover(); r == nil {
panic("expected nil dereference")
}
}
func promotion() {
var a A
// Addressable value receiver.
a.f()
a.g()
func() {
defer expectPanic()
a.h() // dynamic error: nil dereference in a.B.D->f()
}()
a.i()
// Non-addressable value receiver.
A(a).f()
// A(a).g() // static error: cannot call pointer method on A literal.B.C
func() {
defer expectPanic()
A(a).h() // dynamic error: nil dereference in A().B.D->f()
}()
A(a).i()
// Pointer receiver.
(&a).f()
(&a).g()
func() {
defer expectPanic()
(&a).h() // dynamic error: nil deref: nil dereference in (&a).B.D->f()
}()
(&a).i()
c := new(C)
c.f() // makes a copy
c.g()
} }
// skip
// Copyright 2012 The Go Authors. All rights reserved. // Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Test method expressions with arguments. // Test method expressions with arguments.
// This file is not tested by itself; it is imported by method4.go.
package method4a package method4a
......
// Copyright 2012 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.
// Test method expressions with arguments.
package main
import "./method4a"
type T1 int
type T2 struct {
f int
}
type I1 interface {
Sum([]int, int) int
}
type I2 interface {
Sum(a []int, b int) int
}
func (i T1) Sum(a []int, b int) int {
r := int(i) + b
for _, v := range a {
r += v
}
return r
}
func (p *T2) Sum(a []int, b int) int {
r := p.f + b
for _, v := range a {
r += v
}
return r
}
func eq(v1, v2 int) {
if v1 != v2 {
panic(0)
}
}
func main() {
a := []int{1, 2, 3}
t1 := T1(4)
t2 := &T2{4}
eq(t1.Sum(a, 5), 15)
eq(t2.Sum(a, 6), 16)
eq(T1.Sum(t1, a, 7), 17)
eq((*T2).Sum(t2, a, 8), 18)
f1 := T1.Sum
eq(f1(t1, a, 9), 19)
f2 := (*T2).Sum
eq(f2(t2, a, 10), 20)
eq(I1.Sum(t1, a, 11), 21)
eq(I1.Sum(t2, a, 12), 22)
f3 := I1.Sum
eq(f3(t1, a, 13), 23)
eq(f3(t2, a, 14), 24)
eq(I2.Sum(t1, a, 15), 25)
eq(I2.Sum(t2, a, 16), 26)
f4 := I2.Sum
eq(f4(t1, a, 17), 27)
eq(f4(t2, a, 18), 28)
mt1 := method4a.T1(4)
mt2 := &method4a.T2{4}
eq(mt1.Sum(a, 30), 40)
eq(mt2.Sum(a, 31), 41)
eq(method4a.T1.Sum(mt1, a, 32), 42)
eq((*method4a.T2).Sum(mt2, a, 33), 43)
g1 := method4a.T1.Sum
eq(g1(mt1, a, 34), 44)
g2 := (*method4a.T2).Sum
eq(g2(mt2, a, 35), 45)
eq(method4a.I1.Sum(mt1, a, 36), 46)
eq(method4a.I1.Sum(mt2, a, 37), 47)
g3 := method4a.I1.Sum
eq(g3(mt1, a, 38), 48)
eq(g3(mt2, a, 39), 49)
eq(method4a.I2.Sum(mt1, a, 40), 50)
eq(method4a.I2.Sum(mt2, a, 41), 51)
g4 := method4a.I2.Sum
eq(g4(mt1, a, 42), 52)
eq(g4(mt2, a, 43), 53)
}
// $G $D/method4a.go && $G $D/$F.go && $L $F.$A && ./$A.out // rundir
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2012 The Go Authors. All rights reserved. // Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Test method expressions with arguments. // Test method expressions with arguments.
package ignored
package main
import "./method4a"
type T1 int
type T2 struct {
f int
}
type I1 interface {
Sum([]int, int) int
}
type I2 interface {
Sum(a []int, b int) int
}
func (i T1) Sum(a []int, b int) int {
r := int(i) + b
for _, v := range a {
r += v
}
return r
}
func (p *T2) Sum(a []int, b int) int {
r := p.f + b
for _, v := range a {
r += v
}
return r
}
func eq(v1, v2 int) {
if v1 != v2 {
panic(0)
}
}
func main() {
a := []int{1, 2, 3}
t1 := T1(4)
t2 := &T2{4}
eq(t1.Sum(a, 5), 15)
eq(t2.Sum(a, 6), 16)
eq(T1.Sum(t1, a, 7), 17)
eq((*T2).Sum(t2, a, 8), 18)
f1 := T1.Sum
eq(f1(t1, a, 9), 19)
f2 := (*T2).Sum
eq(f2(t2, a, 10), 20)
eq(I1.Sum(t1, a, 11), 21)
eq(I1.Sum(t2, a, 12), 22)
f3 := I1.Sum
eq(f3(t1, a, 13), 23)
eq(f3(t2, a, 14), 24)
eq(I2.Sum(t1, a, 15), 25)
eq(I2.Sum(t2, a, 16), 26)
f4 := I2.Sum
eq(f4(t1, a, 17), 27)
eq(f4(t2, a, 18), 28)
mt1 := method4a.T1(4)
mt2 := &method4a.T2{4}
eq(mt1.Sum(a, 30), 40)
eq(mt2.Sum(a, 31), 41)
eq(method4a.T1.Sum(mt1, a, 32), 42)
eq((*method4a.T2).Sum(mt2, a, 33), 43)
g1 := method4a.T1.Sum
eq(g1(mt1, a, 34), 44)
g2 := (*method4a.T2).Sum
eq(g2(mt2, a, 35), 45)
eq(method4a.I1.Sum(mt1, a, 36), 46)
eq(method4a.I1.Sum(mt2, a, 37), 47)
g3 := method4a.I1.Sum
eq(g3(mt1, a, 38), 48)
eq(g3(mt2, a, 39), 49)
eq(method4a.I2.Sum(mt1, a, 40), 50)
eq(method4a.I2.Sum(mt2, a, 41), 51)
g4 := method4a.I2.Sum
eq(g4(mt1, a, 42), 52)
eq(g4(mt2, a, 43), 53)
}
// run
// Copyright 2013 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 main
// Concrete types implementing M method.
// Smaller than a word, word-sized, larger than a word.
// Value and pointer receivers.
type Tinter interface {
M(int, byte) (byte, int)
}
type Tsmallv byte
func (v Tsmallv) M(x int, b byte) (byte, int) { return b, x+int(v) }
type Tsmallp byte
func (p *Tsmallp) M(x int, b byte) (byte, int) { return b, x+int(*p) }
type Twordv uintptr
func (v Twordv) M(x int, b byte) (byte, int) { return b, x+int(v) }
type Twordp uintptr
func (p *Twordp) M(x int, b byte) (byte, int) { return b, x+int(*p) }
type Tbigv [2]uintptr
func (v Tbigv) M(x int, b byte) (byte, int) { return b, x+int(v[0])+int(v[1]) }
type Tbigp [2]uintptr
func (p *Tbigp) M(x int, b byte) (byte, int) { return b, x+int(p[0])+int(p[1]) }
// Again, with an unexported method.
type tsmallv byte
func (v tsmallv) m(x int, b byte) (byte, int) { return b, x+int(v) }
type tsmallp byte
func (p *tsmallp) m(x int, b byte) (byte, int) { return b, x+int(*p) }
type twordv uintptr
func (v twordv) m(x int, b byte) (byte, int) { return b, x+int(v) }
type twordp uintptr
func (p *twordp) m(x int, b byte) (byte, int) { return b, x+int(*p) }
type tbigv [2]uintptr
func (v tbigv) m(x int, b byte) (byte, int) { return b, x+int(v[0])+int(v[1]) }
type tbigp [2]uintptr
func (p *tbigp) m(x int, b byte) (byte, int) { return b, x+int(p[0])+int(p[1]) }
type tinter interface {
m(int, byte) (byte, int)
}
// Embedding via pointer.
type T1 struct {
T2
}
type T2 struct {
*T3
}
type T3 struct {
*T4
}
type T4 struct {
}
func (t4 T4) M(x int, b byte) (byte, int) { return b, x+40 }
var failed = false
func CheckI(name string, i Tinter, inc int) {
b, x := i.M(1000, 99)
if b != 99 || x != 1000+inc {
failed = true
print(name, ".M(1000, 99) = ", b, ", ", x, " want 99, ", 1000+inc, "\n")
}
CheckF("(i="+name+")", i.M, inc)
}
func CheckF(name string, f func(int, byte) (byte, int), inc int) {
b, x := f(1000, 99)
if b != 99 || x != 1000+inc {
failed = true
print(name, "(1000, 99) = ", b, ", ", x, " want 99, ", 1000+inc, "\n")
}
}
func checkI(name string, i tinter, inc int) {
b, x := i.m(1000, 99)
if b != 99 || x != 1000+inc {
failed = true
print(name, ".m(1000, 99) = ", b, ", ", x, " want 99, ", 1000+inc, "\n")
}
checkF("(i="+name+")", i.m, inc)
}
func checkF(name string, f func(int, byte) (byte, int), inc int) {
b, x := f(1000, 99)
if b != 99 || x != 1000+inc {
failed = true
print(name, "(1000, 99) = ", b, ", ", x, " want 99, ", 1000+inc, "\n")
}
}
func shouldPanic(f func()) {
defer func() {
if recover() == nil {
panic("not panicking")
}
}()
f()
}
func shouldNotPanic(f func()) {
f()
}
func main() {
sv := Tsmallv(1)
CheckI("sv", sv, 1)
CheckF("sv.M", sv.M, 1)
CheckF("(&sv).M", (&sv).M, 1)
psv := &sv
CheckI("psv", psv, 1)
CheckF("psv.M", psv.M, 1)
CheckF("(*psv).M", (*psv).M, 1)
sp := Tsmallp(2)
CheckI("&sp", &sp, 2)
CheckF("sp.M", sp.M, 2)
CheckF("(&sp).M", (&sp).M, 2)
psp := &sp
CheckI("psp", psp, 2)
CheckF("psp.M", psp.M, 2)
CheckF("(*psp).M", (*psp).M, 2)
wv := Twordv(3)
CheckI("wv", wv, 3)
CheckF("wv.M", wv.M, 3)
CheckF("(&wv).M", (&wv).M, 3)
pwv := &wv
CheckI("pwv", pwv, 3)
CheckF("pwv.M", pwv.M, 3)
CheckF("(*pwv).M", (*pwv).M, 3)
wp := Twordp(4)
CheckI("&wp", &wp, 4)
CheckF("wp.M", wp.M, 4)
CheckF("(&wp).M", (&wp).M, 4)
pwp := &wp
CheckI("pwp", pwp, 4)
CheckF("pwp.M", pwp.M, 4)
CheckF("(*pwp).M", (*pwp).M, 4)
bv := Tbigv([2]uintptr{5, 6})
pbv := &bv
CheckI("bv", bv, 11)
CheckF("bv.M", bv.M, 11)
CheckF("(&bv).M", (&bv).M, 11)
CheckI("pbv", pbv, 11)
CheckF("pbv.M", pbv.M, 11)
CheckF("(*pbv).M", (*pbv).M, 11)
bp := Tbigp([2]uintptr{7,8})
CheckI("&bp", &bp, 15)
CheckF("bp.M", bp.M, 15)
CheckF("(&bp).M", (&bp).M, 15)
pbp := &bp
CheckI("pbp", pbp, 15)
CheckF("pbp.M", pbp.M, 15)
CheckF("(*pbp).M", (*pbp).M, 15)
_sv := tsmallv(1)
checkI("_sv", _sv, 1)
checkF("_sv.m", _sv.m, 1)
checkF("(&_sv).m", (&_sv).m, 1)
_psv := &_sv
checkI("_psv", _psv, 1)
checkF("_psv.m", _psv.m, 1)
checkF("(*_psv).m", (*_psv).m, 1)
_sp := tsmallp(2)
checkI("&_sp", &_sp, 2)
checkF("_sp.m", _sp.m, 2)
checkF("(&_sp).m", (&_sp).m, 2)
_psp := &_sp
checkI("_psp", _psp, 2)
checkF("_psp.m", _psp.m, 2)
checkF("(*_psp).m", (*_psp).m, 2)
_wv := twordv(3)
checkI("_wv", _wv, 3)
checkF("_wv.m", _wv.m, 3)
checkF("(&_wv).m", (&_wv).m, 3)
_pwv := &_wv
checkI("_pwv", _pwv, 3)
checkF("_pwv.m", _pwv.m, 3)
checkF("(*_pwv).m", (*_pwv).m, 3)
_wp := twordp(4)
checkI("&_wp", &_wp, 4)
checkF("_wp.m", _wp.m, 4)
checkF("(&_wp).m", (&_wp).m, 4)
_pwp := &_wp
checkI("_pwp", _pwp, 4)
checkF("_pwp.m", _pwp.m, 4)
checkF("(*_pwp).m", (*_pwp).m, 4)
_bv := tbigv([2]uintptr{5, 6})
_pbv := &_bv
checkI("_bv", _bv, 11)
checkF("_bv.m", _bv.m, 11)
checkF("(&_bv).m", (&_bv).m, 11)
checkI("_pbv", _pbv, 11)
checkF("_pbv.m", _pbv.m, 11)
checkF("(*_pbv).m", (*_pbv).m, 11)
_bp := tbigp([2]uintptr{7,8})
checkI("&_bp", &_bp, 15)
checkF("_bp.m", _bp.m, 15)
checkF("(&_bp).m", (&_bp).m, 15)
_pbp := &_bp
checkI("_pbp", _pbp, 15)
checkF("_pbp.m", _pbp.m, 15)
checkF("(*_pbp).m", (*_pbp).m, 15)
t4 := T4{}
t3 := T3{&t4}
t2 := T2{&t3}
t1 := T1{t2}
CheckI("t4", t4, 40)
CheckI("&t4", &t4, 40)
CheckI("t3", t3, 40)
CheckI("&t3", &t3, 40)
CheckI("t2", t2, 40)
CheckI("&t2", &t2, 40)
CheckI("t1", t1, 40)
CheckI("&t1", &t1, 40)
// x.M panics if x is an interface type and is nil,
// or if x.M expands to (*x).M where x is nil,
// or if x.M expands to x.y.z.w.M where something
// along the evaluation of x.y.z.w is nil.
var f func(int, byte) (byte, int)
shouldPanic(func() { psv = nil; f = psv.M })
shouldPanic(func() { pwv = nil; f = pwv.M })
shouldPanic(func() { pbv = nil; f = pbv.M })
shouldPanic(func() { var i Tinter; f = i.M })
shouldPanic(func() { _psv = nil; f = _psv.m })
shouldPanic(func() { _pwv = nil; f = _pwv.m })
shouldPanic(func() { _pbv = nil; f = _pbv.m })
shouldPanic(func() { var _i tinter; f = _i.m })
shouldPanic(func() { var t1 T1; f = t1.M })
shouldPanic(func() { var t2 T2; f = t2.M })
shouldPanic(func() { var t3 *T3; f = t3.M })
shouldPanic(func() { var t3 T3; f = t3.M })
if f != nil {
panic("something set f")
}
// x.M does not panic if x is a nil pointer and
// M is a method with a pointer receiver.
shouldNotPanic(func() { psp = nil; f = psp.M })
shouldNotPanic(func() { pwp = nil; f = pwp.M })
shouldNotPanic(func() { pbp = nil; f = pbp.M })
shouldNotPanic(func() { _psp = nil; f = _psp.m })
shouldNotPanic(func() { _pwp = nil; f = _pwp.m })
shouldNotPanic(func() { _pbp = nil; f = _pbp.m })
shouldNotPanic(func() { var t4 T4; f = t4.M })
if f == nil {
panic("nothing set f")
}
}
...@@ -115,7 +115,7 @@ func chantest() { ...@@ -115,7 +115,7 @@ func chantest() {
}) })
shouldBlock(func() { shouldBlock(func() {
x, ok := <-ch x, ok := <-ch
println(x, ok) println(x, ok) // unreachable
}) })
if len(ch) != 0 { if len(ch) != 0 {
...@@ -147,12 +147,13 @@ func maptest() { ...@@ -147,12 +147,13 @@ func maptest() {
panic(v) panic(v)
} }
// can delete (non-existent) entries
delete(m, 2)
// but cannot be written to // but cannot be written to
shouldPanic(func() { shouldPanic(func() {
m[2] = 3 m[2] = 3
}) })
// can delete (non-existent) entries
delete(m, 2)
} }
// nil slice // nil slice
......
...@@ -38,6 +38,8 @@ func main() { ...@@ -38,6 +38,8 @@ func main() {
shouldPanic(p8) shouldPanic(p8)
shouldPanic(p9) shouldPanic(p9)
shouldPanic(p10) shouldPanic(p10)
shouldPanic(p11)
shouldPanic(p12)
} }
func shouldPanic(f func()) { func shouldPanic(f func()) {
...@@ -130,3 +132,23 @@ func p10() { ...@@ -130,3 +132,23 @@ func p10() {
var t *T var t *T
println(t.i) // should crash println(t.i) // should crash
} }
type T1 struct {
T
}
type T2 struct {
*T1
}
func p11() {
t := &T2{}
p := &t.i
println(*p)
}
// ADDR(DOT(IND(p))) needs a check also
func p12() {
var p *T = nil
println(*(&((*p).i)))
}
// [ "$GORUN" == "" ] || exit 0 # Android runner gets confused by the NUL output // errorcheckoutput
// $G $D/$F.go && $L $F.$A && ./$A.out >tmp.go &&
// errchk $G -e tmp.go
// rm -f tmp.go
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
......
...@@ -55,10 +55,10 @@ func testslice() { ...@@ -55,10 +55,10 @@ func testslice() {
panic("fail") panic("fail")
} }
if s != 15 { if s != 15 {
println("wrong sum ranging over makeslice") println("wrong sum ranging over makeslice", s)
panic("fail") panic("fail")
} }
x := []int{10, 20} x := []int{10, 20}
y := []int{99} y := []int{99}
i := 1 i := 1
...@@ -82,7 +82,7 @@ func testslice1() { ...@@ -82,7 +82,7 @@ func testslice1() {
panic("fail") panic("fail")
} }
if s != 10 { if s != 10 {
println("wrong sum ranging over makeslice") println("wrong sum ranging over makeslice", s)
panic("fail") panic("fail")
} }
} }
...@@ -106,7 +106,7 @@ func testarray() { ...@@ -106,7 +106,7 @@ func testarray() {
panic("fail") panic("fail")
} }
if s != 15 { if s != 15 {
println("wrong sum ranging over makearray") println("wrong sum ranging over makearray", s)
panic("fail") panic("fail")
} }
} }
...@@ -122,7 +122,7 @@ func testarray1() { ...@@ -122,7 +122,7 @@ func testarray1() {
panic("fail") panic("fail")
} }
if s != 10 { if s != 10 {
println("wrong sum ranging over makearray") println("wrong sum ranging over makearray", s)
panic("fail") panic("fail")
} }
} }
...@@ -155,7 +155,7 @@ func testarrayptr() { ...@@ -155,7 +155,7 @@ func testarrayptr() {
panic("fail") panic("fail")
} }
if s != 15 { if s != 15 {
println("wrong sum ranging over makearrayptr") println("wrong sum ranging over makearrayptr", s)
panic("fail") panic("fail")
} }
} }
...@@ -171,7 +171,7 @@ func testarrayptr1() { ...@@ -171,7 +171,7 @@ func testarrayptr1() {
panic("fail") panic("fail")
} }
if s != 10 { if s != 10 {
println("wrong sum ranging over makearrayptr") println("wrong sum ranging over makearrayptr", s)
panic("fail") panic("fail")
} }
} }
...@@ -195,7 +195,7 @@ func teststring() { ...@@ -195,7 +195,7 @@ func teststring() {
panic("fail") panic("fail")
} }
if s != 'a'+'b'+'c'+'d'+'☺' { if s != 'a'+'b'+'c'+'d'+'☺' {
println("wrong sum ranging over makestring") println("wrong sum ranging over makestring", s)
panic("fail") panic("fail")
} }
} }
...@@ -211,7 +211,7 @@ func teststring1() { ...@@ -211,7 +211,7 @@ func teststring1() {
panic("fail") panic("fail")
} }
if s != 10 { if s != 10 {
println("wrong sum ranging over makestring") println("wrong sum ranging over makestring", s)
panic("fail") panic("fail")
} }
} }
...@@ -235,7 +235,7 @@ func testmap() { ...@@ -235,7 +235,7 @@ func testmap() {
panic("fail") panic("fail")
} }
if s != 'a'+'b'+'c'+'d'+'☺' { if s != 'a'+'b'+'c'+'d'+'☺' {
println("wrong sum ranging over makemap") println("wrong sum ranging over makemap", s)
panic("fail") panic("fail")
} }
} }
...@@ -251,7 +251,7 @@ func testmap1() { ...@@ -251,7 +251,7 @@ func testmap1() {
panic("fail") panic("fail")
} }
if s != 10 { if s != 10 {
println("wrong sum ranging over makemap") println("wrong sum ranging over makemap", s)
panic("fail") panic("fail")
} }
} }
......
...@@ -8,15 +8,21 @@ ...@@ -8,15 +8,21 @@
package main package main
import "runtime" import (
"os"
"runtime"
)
func main() { func main() {
test1() test1()
test1WithClosures() test1WithClosures()
test2() test2()
test3() test3()
test4() // exp/ssa/interp still has some bugs in recover().
test5() if os.Getenv("GOSSAINTERP") == "" {
test4()
test5()
}
test6() test6()
test6WithClosures() test6WithClosures()
test7() test7()
......
...@@ -71,6 +71,10 @@ func main() { ...@@ -71,6 +71,10 @@ func main() {
inter = 1 inter = 1
check("type-concrete", func() { println(inter.(string)) }, "int, not string") check("type-concrete", func() { println(inter.(string)) }, "int, not string")
check("type-interface", func() { println(inter.(m)) }, "missing method m") check("type-interface", func() { println(inter.(m)) }, "missing method m")
if didbug {
panic("recover3")
}
} }
type m interface { type m interface {
......
...@@ -8,7 +8,10 @@ ...@@ -8,7 +8,10 @@
package main package main
import "fmt" import (
"fmt"
"runtime"
)
func main() { func main() {
n := n :=
...@@ -52,6 +55,7 @@ func main() { ...@@ -52,6 +55,7 @@ func main() {
iota iota
if n != NUM*(NUM-1)/2 { if n != NUM*(NUM-1)/2 {
fmt.Println("BUG: wrong n", n, NUM*(NUM-1)/2) fmt.Println("BUG: wrong n", n, NUM*(NUM-1)/2)
runtime.Breakpoint() // panic is inaccessible
} }
} }
......
...@@ -19,7 +19,6 @@ func main() { ...@@ -19,7 +19,6 @@ func main() {
p6() p6()
p7() p7()
p8() p8()
p9()
} }
var gx []int var gx []int
...@@ -43,7 +42,7 @@ func check3(x, y, z, xx, yy, zz int) { ...@@ -43,7 +42,7 @@ func check3(x, y, z, xx, yy, zz int) {
} }
func p1() { func p1() {
x := []int{1,2,3} x := []int{1, 2, 3}
i := 0 i := 0
i, x[i] = 1, 100 i, x[i] = 1, 100
_ = i _ = i
...@@ -51,7 +50,7 @@ func p1() { ...@@ -51,7 +50,7 @@ func p1() {
} }
func p2() { func p2() {
x := []int{1,2,3} x := []int{1, 2, 3}
i := 0 i := 0
x[i], i = 100, 1 x[i], i = 100, 1
_ = i _ = i
...@@ -59,7 +58,7 @@ func p2() { ...@@ -59,7 +58,7 @@ func p2() {
} }
func p3() { func p3() {
x := []int{1,2,3} x := []int{1, 2, 3}
y := x y := x
gx = x gx = x
x[1], y[0] = f(0), f(1) x[1], y[0] = f(0), f(1)
...@@ -67,7 +66,7 @@ func p3() { ...@@ -67,7 +66,7 @@ func p3() {
} }
func p4() { func p4() {
x := []int{1,2,3} x := []int{1, 2, 3}
y := x y := x
gx = x gx = x
x[1], y[0] = gx[0], gx[1] x[1], y[0] = gx[0], gx[1]
...@@ -75,7 +74,7 @@ func p4() { ...@@ -75,7 +74,7 @@ func p4() {
} }
func p5() { func p5() {
x := []int{1,2,3} x := []int{1, 2, 3}
y := x y := x
p := &x[0] p := &x[0]
q := &x[1] q := &x[1]
...@@ -90,7 +89,7 @@ func p6() { ...@@ -90,7 +89,7 @@ func p6() {
px := &x px := &x
py := &y py := &y
*px, *py = y, x *px, *py = y, x
check3(x, y, z, 2, 1, 3) check3(x, y, z, 2, 1, 3)
} }
func f1(x, y, z int) (xx, yy, zz int) { func f1(x, y, z int) (xx, yy, zz int) {
...@@ -107,21 +106,6 @@ func p7() { ...@@ -107,21 +106,6 @@ func p7() {
} }
func p8() { func p8() {
x := []int{1,2,3}
defer func() {
err := recover()
if err == nil {
panic("not panicking")
}
check(x, 100, 2, 3)
}()
i := 0
i, x[i], x[5] = 1, 100, 500
}
func p9() {
m := make(map[int]int) m := make(map[int]int)
m[0] = len(m) m[0] = len(m)
if m[0] != 0 { if m[0] != 0 {
......
// errorcheck
// Copyright 2013 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.
// Test compiler diagnosis of function missing return statements.
// See issue 65 and golang.org/s/go11return.
package p
type T int
var x interface{}
var c chan int
func external() int // ok
func _() int {
} // ERROR "missing return"
func _() int {
print(1)
} // ERROR "missing return"
// return is okay
func _() int {
print(1)
return 2
}
// goto is okay
func _() int {
L:
print(1)
goto L
}
// panic is okay
func _() int {
print(1)
panic(2)
}
// but only builtin panic
func _() int {
var panic = func(int) {}
print(1)
panic(2)
} // ERROR "missing return"
// block ending in terminating statement is okay
func _() int {
{
print(1)
return 2
}
}
// block ending in terminating statement is okay
func _() int {
L:
{
print(1)
goto L
}
}
// block ending in terminating statement is okay
func _() int {
print(1)
{
panic(2)
}
}
// adding more code - even though it is dead - now requires a return
func _() int {
print(1)
return 2
print(3)
} // ERROR "missing return"
func _() int {
L:
print(1)
goto L
print(3)
} // ERROR "missing return"
func _() int {
print(1)
panic(2)
print(3)
} // ERROR "missing return"
func _() int {
{
print(1)
return 2
print(3)
}
} // ERROR "missing return"
func _() int {
L:
{
print(1)
goto L
print(3)
}
} // ERROR "missing return"
func _() int {
print(1)
{
panic(2)
print(3)
}
} // ERROR "missing return"
func _() int {
{
print(1)
return 2
}
print(3)
} // ERROR "missing return"
func _() int {
L:
{
print(1)
goto L
}
print(3)
} // ERROR "missing return"
func _() int {
print(1)
{
panic(2)
}
print(3)
} // ERROR "missing return"
// even an empty dead block triggers the message, because it
// becomes the final statement.
func _() int {
print(1)
return 2
{}
} // ERROR "missing return"
func _() int {
L:
print(1)
goto L
{}
} // ERROR "missing return"
func _() int {
print(1)
panic(2)
{}
} // ERROR "missing return"
func _() int {
{
print(1)
return 2
{}
}
} // ERROR "missing return"
func _() int {
L:
{
print(1)
goto L
{}
}
} // ERROR "missing return"
func _() int {
print(1)
{
panic(2)
{}
}
} // ERROR "missing return"
func _() int {
{
print(1)
return 2
}
{}
} // ERROR "missing return"
func _() int {
L:
{
print(1)
goto L
}
{}
} // ERROR "missing return"
func _() int {
print(1)
{
panic(2)
}
{}
} // ERROR "missing return"
// if-else chain with final else and all terminating is okay
func _() int {
print(1)
if x == nil {
panic(2)
} else {
panic(3)
}
}
func _() int {
L:
print(1)
if x == nil {
panic(2)
} else {
goto L
}
}
func _() int {
L:
print(1)
if x == nil {
panic(2)
} else if x == 1 {
return 0
} else if x != 2 {
panic(3)
} else {
goto L
}
}
// if-else chain missing final else is not okay, even if the
// conditions cover every possible case.
func _() int {
print(1)
if x == nil {
panic(2)
} else if x != nil {
panic(3)
}
} // ERROR "missing return"
func _() int {
print(1)
if x == nil {
panic(2)
}
} // ERROR "missing return"
func _() int {
print(1)
if x == nil {
panic(2)
} else if x == 1 {
return 0
} else if x != 1 {
panic(3)
}
} // ERROR "missing return"
// for { loops that never break are okay.
func _() int {
print(1)
for {}
}
func _() int {
for {
for {
break
}
}
}
func _() int {
for {
L:
for {
break L
}
}
}
// for { loops that break are not okay.
func _() int {
print(1)
for { break }
} // ERROR "missing return"
func _() int {
for {
for {
}
break
}
} // ERROR "missing return"
func _() int {
L:
for {
for {
break L
}
}
} // ERROR "missing return"
// if there's a condition - even "true" - the loops are no longer syntactically terminating
func _() int {
print(1)
for x == nil {}
} // ERROR "missing return"
func _() int {
for x == nil {
for {
break
}
}
} // ERROR "missing return"
func _() int {
for x == nil {
L:
for {
break L
}
}
} // ERROR "missing return"
func _() int {
print(1)
for true {}
} // ERROR "missing return"
func _() int {
for true {
for {
break
}
}
} // ERROR "missing return"
func _() int {
for true {
L:
for {
break L
}
}
} // ERROR "missing return"
// select in which all cases terminate and none break are okay.
func _() int {
print(1)
select{}
}
func _() int {
print(1)
select {
case <-c:
print(2)
panic("abc")
}
}
func _() int {
print(1)
select {
case <-c:
print(2)
for{}
}
}
func _() int {
L:
print(1)
select {
case <-c:
print(2)
panic("abc")
case c <- 1:
print(2)
goto L
}
}
func _() int {
print(1)
select {
case <-c:
print(2)
panic("abc")
default:
select{}
}
}
// if any cases don't terminate, the select isn't okay anymore
func _() int {
print(1)
select {
case <-c:
print(2)
}
} // ERROR "missing return"
func _() int {
L:
print(1)
select {
case <-c:
print(2)
panic("abc")
goto L
case c <- 1:
print(2)
}
} // ERROR "missing return"
func _() int {
print(1)
select {
case <-c:
print(2)
panic("abc")
default:
print(2)
}
} // ERROR "missing return"
// if any breaks refer to the select, the select isn't okay anymore, even if they're dead
func _() int {
print(1)
select{ default: break }
} // ERROR "missing return"
func _() int {
print(1)
select {
case <-c:
print(2)
panic("abc")
break
}
} // ERROR "missing return"
func _() int {
print(1)
L:
select {
case <-c:
print(2)
for{ break L }
}
} // ERROR "missing return"
func _() int {
print(1)
L:
select {
case <-c:
print(2)
panic("abc")
case c <- 1:
print(2)
break L
}
} // ERROR "missing return"
func _() int {
print(1)
select {
case <-c:
print(1)
panic("abc")
default:
select{}
break
}
} // ERROR "missing return"
// switch with default in which all cases terminate is okay
func _() int {
print(1)
switch x {
case 1:
print(2)
panic(3)
default:
return 4
}
}
func _() int {
print(1)
switch x {
default:
return 4
case 1:
print(2)
panic(3)
}
}
func _() int {
print(1)
switch x {
case 1:
print(2)
fallthrough
default:
return 4
}
}
// if no default or some case doesn't terminate, switch is no longer okay
func _() int {
print(1)
switch {
}
} // ERROR "missing return"
func _() int {
print(1)
switch x {
case 1:
print(2)
panic(3)
case 2:
return 4
}
} // ERROR "missing return"
func _() int {
print(1)
switch x {
case 2:
return 4
case 1:
print(2)
panic(3)
}
} // ERROR "missing return"
func _() int {
print(1)
switch x {
case 1:
print(2)
fallthrough
case 2:
return 4
}
} // ERROR "missing return"
func _() int {
print(1)
switch x {
case 1:
print(2)
panic(3)
}
} // ERROR "missing return"
// if any breaks refer to the switch, switch is no longer okay
func _() int {
print(1)
L:
switch x {
case 1:
print(2)
panic(3)
break L
default:
return 4
}
} // ERROR "missing return"
func _() int {
print(1)
switch x {
default:
return 4
break
case 1:
print(2)
panic(3)
}
} // ERROR "missing return"
func _() int {
print(1)
L:
switch x {
case 1:
print(2)
for {
break L
}
default:
return 4
}
} // ERROR "missing return"
// type switch with default in which all cases terminate is okay
func _() int {
print(1)
switch x.(type) {
case int:
print(2)
panic(3)
default:
return 4
}
}
func _() int {
print(1)
switch x.(type) {
default:
return 4
case int:
print(2)
panic(3)
}
}
// if no default or some case doesn't terminate, switch is no longer okay
func _() int {
print(1)
switch {
}
} // ERROR "missing return"
func _() int {
print(1)
switch x.(type) {
case int:
print(2)
panic(3)
case float64:
return 4
}
} // ERROR "missing return"
func _() int {
print(1)
switch x.(type) {
case float64:
return 4
case int:
print(2)
panic(3)
}
} // ERROR "missing return"
func _() int {
print(1)
switch x.(type) {
case int:
print(2)
panic(3)
}
} // ERROR "missing return"
// if any breaks refer to the switch, switch is no longer okay
func _() int {
print(1)
L:
switch x.(type) {
case int:
print(2)
panic(3)
break L
default:
return 4
}
} // ERROR "missing return"
func _() int {
print(1)
switch x.(type) {
default:
return 4
break
case int:
print(2)
panic(3)
}
} // ERROR "missing return"
func _() int {
print(1)
L:
switch x.(type) {
case int:
print(2)
for {
break L
}
default:
return 4
}
} // ERROR "missing return"
// again, but without the leading print(1).
// testing that everything works when the terminating statement is first.
func _() int {
} // ERROR "missing return"
// return is okay
func _() int {
return 2
}
// goto is okay
func _() int {
L:
goto L
}
// panic is okay
func _() int {
panic(2)
}
// but only builtin panic
func _() int {
var panic = func(int) {}
panic(2)
} // ERROR "missing return"
// block ending in terminating statement is okay
func _() int {
{
return 2
}
}
// block ending in terminating statement is okay
func _() int {
L:
{
goto L
}
}
// block ending in terminating statement is okay
func _() int {
{
panic(2)
}
}
// adding more code - even though it is dead - now requires a return
func _() int {
return 2
print(3)
} // ERROR "missing return"
func _() int {
L:
goto L
print(3)
} // ERROR "missing return"
func _() int {
panic(2)
print(3)
} // ERROR "missing return"
func _() int {
{
return 2
print(3)
}
} // ERROR "missing return"
func _() int {
L:
{
goto L
print(3)
}
} // ERROR "missing return"
func _() int {
{
panic(2)
print(3)
}
} // ERROR "missing return"
func _() int {
{
return 2
}
print(3)
} // ERROR "missing return"
func _() int {
L:
{
goto L
}
print(3)
} // ERROR "missing return"
func _() int {
{
panic(2)
}
print(3)
} // ERROR "missing return"
// even an empty dead block triggers the message, because it
// becomes the final statement.
func _() int {
return 2
{}
} // ERROR "missing return"
func _() int {
L:
goto L
{}
} // ERROR "missing return"
func _() int {
panic(2)
{}
} // ERROR "missing return"
func _() int {
{
return 2
{}
}
} // ERROR "missing return"
func _() int {
L:
{
goto L
{}
}
} // ERROR "missing return"
func _() int {
{
panic(2)
{}
}
} // ERROR "missing return"
func _() int {
{
return 2
}
{}
} // ERROR "missing return"
func _() int {
L:
{
goto L
}
{}
} // ERROR "missing return"
func _() int {
{
panic(2)
}
{}
} // ERROR "missing return"
// if-else chain with final else and all terminating is okay
func _() int {
if x == nil {
panic(2)
} else {
panic(3)
}
}
func _() int {
L:
if x == nil {
panic(2)
} else {
goto L
}
}
func _() int {
L:
if x == nil {
panic(2)
} else if x == 1 {
return 0
} else if x != 2 {
panic(3)
} else {
goto L
}
}
// if-else chain missing final else is not okay, even if the
// conditions cover every possible case.
func _() int {
if x == nil {
panic(2)
} else if x != nil {
panic(3)
}
} // ERROR "missing return"
func _() int {
if x == nil {
panic(2)
}
} // ERROR "missing return"
func _() int {
if x == nil {
panic(2)
} else if x == 1 {
return 0
} else if x != 1 {
panic(3)
}
} // ERROR "missing return"
// for { loops that never break are okay.
func _() int {
for {}
}
func _() int {
for {
for {
break
}
}
}
func _() int {
for {
L:
for {
break L
}
}
}
// for { loops that break are not okay.
func _() int {
for { break }
} // ERROR "missing return"
func _() int {
for {
for {
}
break
}
} // ERROR "missing return"
func _() int {
L:
for {
for {
break L
}
}
} // ERROR "missing return"
// if there's a condition - even "true" - the loops are no longer syntactically terminating
func _() int {
for x == nil {}
} // ERROR "missing return"
func _() int {
for x == nil {
for {
break
}
}
} // ERROR "missing return"
func _() int {
for x == nil {
L:
for {
break L
}
}
} // ERROR "missing return"
func _() int {
for true {}
} // ERROR "missing return"
func _() int {
for true {
for {
break
}
}
} // ERROR "missing return"
func _() int {
for true {
L:
for {
break L
}
}
} // ERROR "missing return"
// select in which all cases terminate and none break are okay.
func _() int {
select{}
}
func _() int {
select {
case <-c:
print(2)
panic("abc")
}
}
func _() int {
select {
case <-c:
print(2)
for{}
}
}
func _() int {
L:
select {
case <-c:
print(2)
panic("abc")
case c <- 1:
print(2)
goto L
}
}
func _() int {
select {
case <-c:
print(2)
panic("abc")
default:
select{}
}
}
// if any cases don't terminate, the select isn't okay anymore
func _() int {
select {
case <-c:
print(2)
}
} // ERROR "missing return"
func _() int {
L:
select {
case <-c:
print(2)
panic("abc")
goto L
case c <- 1:
print(2)
}
} // ERROR "missing return"
func _() int {
select {
case <-c:
print(2)
panic("abc")
default:
print(2)
}
} // ERROR "missing return"
// if any breaks refer to the select, the select isn't okay anymore, even if they're dead
func _() int {
select{ default: break }
} // ERROR "missing return"
func _() int {
select {
case <-c:
print(2)
panic("abc")
break
}
} // ERROR "missing return"
func _() int {
L:
select {
case <-c:
print(2)
for{ break L }
}
} // ERROR "missing return"
func _() int {
L:
select {
case <-c:
print(2)
panic("abc")
case c <- 1:
print(2)
break L
}
} // ERROR "missing return"
func _() int {
select {
case <-c:
panic("abc")
default:
select{}
break
}
} // ERROR "missing return"
// switch with default in which all cases terminate is okay
func _() int {
switch x {
case 1:
print(2)
panic(3)
default:
return 4
}
}
func _() int {
switch x {
default:
return 4
case 1:
print(2)
panic(3)
}
}
func _() int {
switch x {
case 1:
print(2)
fallthrough
default:
return 4
}
}
// if no default or some case doesn't terminate, switch is no longer okay
func _() int {
switch {
}
} // ERROR "missing return"
func _() int {
switch x {
case 1:
print(2)
panic(3)
case 2:
return 4
}
} // ERROR "missing return"
func _() int {
switch x {
case 2:
return 4
case 1:
print(2)
panic(3)
}
} // ERROR "missing return"
func _() int {
switch x {
case 1:
print(2)
fallthrough
case 2:
return 4
}
} // ERROR "missing return"
func _() int {
switch x {
case 1:
print(2)
panic(3)
}
} // ERROR "missing return"
// if any breaks refer to the switch, switch is no longer okay
func _() int {
L:
switch x {
case 1:
print(2)
panic(3)
break L
default:
return 4
}
} // ERROR "missing return"
func _() int {
switch x {
default:
return 4
break
case 1:
print(2)
panic(3)
}
} // ERROR "missing return"
func _() int {
L:
switch x {
case 1:
print(2)
for {
break L
}
default:
return 4
}
} // ERROR "missing return"
// type switch with default in which all cases terminate is okay
func _() int {
switch x.(type) {
case int:
print(2)
panic(3)
default:
return 4
}
}
func _() int {
switch x.(type) {
default:
return 4
case int:
print(2)
panic(3)
}
}
// if no default or some case doesn't terminate, switch is no longer okay
func _() int {
switch {
}
} // ERROR "missing return"
func _() int {
switch x.(type) {
case int:
print(2)
panic(3)
case float64:
return 4
}
} // ERROR "missing return"
func _() int {
switch x.(type) {
case float64:
return 4
case int:
print(2)
panic(3)
}
} // ERROR "missing return"
func _() int {
switch x.(type) {
case int:
print(2)
panic(3)
}
} // ERROR "missing return"
// if any breaks refer to the switch, switch is no longer okay
func _() int {
L:
switch x.(type) {
case int:
print(2)
panic(3)
break L
default:
return 4
}
} // ERROR "missing return"
func _() int {
switch x.(type) {
default:
return 4
break
case int:
print(2)
panic(3)
}
} // ERROR "missing return"
func _() int {
L:
switch x.(type) {
case int:
print(2)
for {
break L
}
default:
return 4
}
} // ERROR "missing return"
func _() int {
switch x.(type) {
default:
return 4
case int, float64:
print(2)
panic(3)
}
}
// again, with func literals
var _ = func() int {
} // ERROR "missing return"
var _ = func() int {
print(1)
} // ERROR "missing return"
// return is okay
var _ = func() int {
print(1)
return 2
}
// goto is okay
var _ = func() int {
L:
print(1)
goto L
}
// panic is okay
var _ = func() int {
print(1)
panic(2)
}
// but only builtin panic
var _ = func() int {
var panic = func(int) {}
print(1)
panic(2)
} // ERROR "missing return"
// block ending in terminating statement is okay
var _ = func() int {
{
print(1)
return 2
}
}
// block ending in terminating statement is okay
var _ = func() int {
L:
{
print(1)
goto L
}
}
// block ending in terminating statement is okay
var _ = func() int {
print(1)
{
panic(2)
}
}
// adding more code - even though it is dead - now requires a return
var _ = func() int {
print(1)
return 2
print(3)
} // ERROR "missing return"
var _ = func() int {
L:
print(1)
goto L
print(3)
} // ERROR "missing return"
var _ = func() int {
print(1)
panic(2)
print(3)
} // ERROR "missing return"
var _ = func() int {
{
print(1)
return 2
print(3)
}
} // ERROR "missing return"
var _ = func() int {
L:
{
print(1)
goto L
print(3)
}
} // ERROR "missing return"
var _ = func() int {
print(1)
{
panic(2)
print(3)
}
} // ERROR "missing return"
var _ = func() int {
{
print(1)
return 2
}
print(3)
} // ERROR "missing return"
var _ = func() int {
L:
{
print(1)
goto L
}
print(3)
} // ERROR "missing return"
var _ = func() int {
print(1)
{
panic(2)
}
print(3)
} // ERROR "missing return"
// even an empty dead block triggers the message, because it
// becomes the final statement.
var _ = func() int {
print(1)
return 2
{}
} // ERROR "missing return"
var _ = func() int {
L:
print(1)
goto L
{}
} // ERROR "missing return"
var _ = func() int {
print(1)
panic(2)
{}
} // ERROR "missing return"
var _ = func() int {
{
print(1)
return 2
{}
}
} // ERROR "missing return"
var _ = func() int {
L:
{
print(1)
goto L
{}
}
} // ERROR "missing return"
var _ = func() int {
print(1)
{
panic(2)
{}
}
} // ERROR "missing return"
var _ = func() int {
{
print(1)
return 2
}
{}
} // ERROR "missing return"
var _ = func() int {
L:
{
print(1)
goto L
}
{}
} // ERROR "missing return"
var _ = func() int {
print(1)
{
panic(2)
}
{}
} // ERROR "missing return"
// if-else chain with final else and all terminating is okay
var _ = func() int {
print(1)
if x == nil {
panic(2)
} else {
panic(3)
}
}
var _ = func() int {
L:
print(1)
if x == nil {
panic(2)
} else {
goto L
}
}
var _ = func() int {
L:
print(1)
if x == nil {
panic(2)
} else if x == 1 {
return 0
} else if x != 2 {
panic(3)
} else {
goto L
}
}
// if-else chain missing final else is not okay, even if the
// conditions cover every possible case.
var _ = func() int {
print(1)
if x == nil {
panic(2)
} else if x != nil {
panic(3)
}
} // ERROR "missing return"
var _ = func() int {
print(1)
if x == nil {
panic(2)
}
} // ERROR "missing return"
var _ = func() int {
print(1)
if x == nil {
panic(2)
} else if x == 1 {
return 0
} else if x != 1 {
panic(3)
}
} // ERROR "missing return"
// for { loops that never break are okay.
var _ = func() int {
print(1)
for {}
}
var _ = func() int {
for {
for {
break
}
}
}
var _ = func() int {
for {
L:
for {
break L
}
}
}
// for { loops that break are not okay.
var _ = func() int {
print(1)
for { break }
} // ERROR "missing return"
var _ = func() int {
for {
for {
}
break
}
} // ERROR "missing return"
var _ = func() int {
L:
for {
for {
break L
}
}
} // ERROR "missing return"
// if there's a condition - even "true" - the loops are no longer syntactically terminating
var _ = func() int {
print(1)
for x == nil {}
} // ERROR "missing return"
var _ = func() int {
for x == nil {
for {
break
}
}
} // ERROR "missing return"
var _ = func() int {
for x == nil {
L:
for {
break L
}
}
} // ERROR "missing return"
var _ = func() int {
print(1)
for true {}
} // ERROR "missing return"
var _ = func() int {
for true {
for {
break
}
}
} // ERROR "missing return"
var _ = func() int {
for true {
L:
for {
break L
}
}
} // ERROR "missing return"
// select in which all cases terminate and none break are okay.
var _ = func() int {
print(1)
select{}
}
var _ = func() int {
print(1)
select {
case <-c:
print(2)
panic("abc")
}
}
var _ = func() int {
print(1)
select {
case <-c:
print(2)
for{}
}
}
var _ = func() int {
L:
print(1)
select {
case <-c:
print(2)
panic("abc")
case c <- 1:
print(2)
goto L
}
}
var _ = func() int {
print(1)
select {
case <-c:
print(2)
panic("abc")
default:
select{}
}
}
// if any cases don't terminate, the select isn't okay anymore
var _ = func() int {
print(1)
select {
case <-c:
print(2)
}
} // ERROR "missing return"
var _ = func() int {
L:
print(1)
select {
case <-c:
print(2)
panic("abc")
goto L
case c <- 1:
print(2)
}
} // ERROR "missing return"
var _ = func() int {
print(1)
select {
case <-c:
print(2)
panic("abc")
default:
print(2)
}
} // ERROR "missing return"
// if any breaks refer to the select, the select isn't okay anymore, even if they're dead
var _ = func() int {
print(1)
select{ default: break }
} // ERROR "missing return"
var _ = func() int {
print(1)
select {
case <-c:
print(2)
panic("abc")
break
}
} // ERROR "missing return"
var _ = func() int {
print(1)
L:
select {
case <-c:
print(2)
for{ break L }
}
} // ERROR "missing return"
var _ = func() int {
print(1)
L:
select {
case <-c:
print(2)
panic("abc")
case c <- 1:
print(2)
break L
}
} // ERROR "missing return"
var _ = func() int {
print(1)
select {
case <-c:
print(1)
panic("abc")
default:
select{}
break
}
} // ERROR "missing return"
// switch with default in which all cases terminate is okay
var _ = func() int {
print(1)
switch x {
case 1:
print(2)
panic(3)
default:
return 4
}
}
var _ = func() int {
print(1)
switch x {
default:
return 4
case 1:
print(2)
panic(3)
}
}
var _ = func() int {
print(1)
switch x {
case 1:
print(2)
fallthrough
default:
return 4
}
}
// if no default or some case doesn't terminate, switch is no longer okay
var _ = func() int {
print(1)
switch {
}
} // ERROR "missing return"
var _ = func() int {
print(1)
switch x {
case 1:
print(2)
panic(3)
case 2:
return 4
}
} // ERROR "missing return"
var _ = func() int {
print(1)
switch x {
case 2:
return 4
case 1:
print(2)
panic(3)
}
} // ERROR "missing return"
var _ = func() int {
print(1)
switch x {
case 1:
print(2)
fallthrough
case 2:
return 4
}
} // ERROR "missing return"
var _ = func() int {
print(1)
switch x {
case 1:
print(2)
panic(3)
}
} // ERROR "missing return"
// if any breaks refer to the switch, switch is no longer okay
var _ = func() int {
print(1)
L:
switch x {
case 1:
print(2)
panic(3)
break L
default:
return 4
}
} // ERROR "missing return"
var _ = func() int {
print(1)
switch x {
default:
return 4
break
case 1:
print(2)
panic(3)
}
} // ERROR "missing return"
var _ = func() int {
print(1)
L:
switch x {
case 1:
print(2)
for {
break L
}
default:
return 4
}
} // ERROR "missing return"
// type switch with default in which all cases terminate is okay
var _ = func() int {
print(1)
switch x.(type) {
case int:
print(2)
panic(3)
default:
return 4
}
}
var _ = func() int {
print(1)
switch x.(type) {
default:
return 4
case int:
print(2)
panic(3)
}
}
// if no default or some case doesn't terminate, switch is no longer okay
var _ = func() int {
print(1)
switch {
}
} // ERROR "missing return"
var _ = func() int {
print(1)
switch x.(type) {
case int:
print(2)
panic(3)
case float64:
return 4
}
} // ERROR "missing return"
var _ = func() int {
print(1)
switch x.(type) {
case float64:
return 4
case int:
print(2)
panic(3)
}
} // ERROR "missing return"
var _ = func() int {
print(1)
switch x.(type) {
case int:
print(2)
panic(3)
}
} // ERROR "missing return"
// if any breaks refer to the switch, switch is no longer okay
var _ = func() int {
print(1)
L:
switch x.(type) {
case int:
print(2)
panic(3)
break L
default:
return 4
}
} // ERROR "missing return"
var _ = func() int {
print(1)
switch x.(type) {
default:
return 4
break
case int:
print(2)
panic(3)
}
} // ERROR "missing return"
var _ = func() int {
print(1)
L:
switch x.(type) {
case int:
print(2)
for {
break L
}
default:
return 4
}
} // ERROR "missing return"
// again, but without the leading print(1).
// testing that everything works when the terminating statement is first.
var _ = func() int {
} // ERROR "missing return"
// return is okay
var _ = func() int {
return 2
}
// goto is okay
var _ = func() int {
L:
goto L
}
// panic is okay
var _ = func() int {
panic(2)
}
// but only builtin panic
var _ = func() int {
var panic = func(int) {}
panic(2)
} // ERROR "missing return"
// block ending in terminating statement is okay
var _ = func() int {
{
return 2
}
}
// block ending in terminating statement is okay
var _ = func() int {
L:
{
goto L
}
}
// block ending in terminating statement is okay
var _ = func() int {
{
panic(2)
}
}
// adding more code - even though it is dead - now requires a return
var _ = func() int {
return 2
print(3)
} // ERROR "missing return"
var _ = func() int {
L:
goto L
print(3)
} // ERROR "missing return"
var _ = func() int {
panic(2)
print(3)
} // ERROR "missing return"
var _ = func() int {
{
return 2
print(3)
}
} // ERROR "missing return"
var _ = func() int {
L:
{
goto L
print(3)
}
} // ERROR "missing return"
var _ = func() int {
{
panic(2)
print(3)
}
} // ERROR "missing return"
var _ = func() int {
{
return 2
}
print(3)
} // ERROR "missing return"
var _ = func() int {
L:
{
goto L
}
print(3)
} // ERROR "missing return"
var _ = func() int {
{
panic(2)
}
print(3)
} // ERROR "missing return"
// even an empty dead block triggers the message, because it
// becomes the final statement.
var _ = func() int {
return 2
{}
} // ERROR "missing return"
var _ = func() int {
L:
goto L
{}
} // ERROR "missing return"
var _ = func() int {
panic(2)
{}
} // ERROR "missing return"
var _ = func() int {
{
return 2
{}
}
} // ERROR "missing return"
var _ = func() int {
L:
{
goto L
{}
}
} // ERROR "missing return"
var _ = func() int {
{
panic(2)
{}
}
} // ERROR "missing return"
var _ = func() int {
{
return 2
}
{}
} // ERROR "missing return"
var _ = func() int {
L:
{
goto L
}
{}
} // ERROR "missing return"
var _ = func() int {
{
panic(2)
}
{}
} // ERROR "missing return"
// if-else chain with final else and all terminating is okay
var _ = func() int {
if x == nil {
panic(2)
} else {
panic(3)
}
}
var _ = func() int {
L:
if x == nil {
panic(2)
} else {
goto L
}
}
var _ = func() int {
L:
if x == nil {
panic(2)
} else if x == 1 {
return 0
} else if x != 2 {
panic(3)
} else {
goto L
}
}
// if-else chain missing final else is not okay, even if the
// conditions cover every possible case.
var _ = func() int {
if x == nil {
panic(2)
} else if x != nil {
panic(3)
}
} // ERROR "missing return"
var _ = func() int {
if x == nil {
panic(2)
}
} // ERROR "missing return"
var _ = func() int {
if x == nil {
panic(2)
} else if x == 1 {
return 0
} else if x != 1 {
panic(3)
}
} // ERROR "missing return"
// for { loops that never break are okay.
var _ = func() int {
for {}
}
var _ = func() int {
for {
for {
break
}
}
}
var _ = func() int {
for {
L:
for {
break L
}
}
}
// for { loops that break are not okay.
var _ = func() int {
for { break }
} // ERROR "missing return"
var _ = func() int {
for {
for {
}
break
}
} // ERROR "missing return"
var _ = func() int {
L:
for {
for {
break L
}
}
} // ERROR "missing return"
// if there's a condition - even "true" - the loops are no longer syntactically terminating
var _ = func() int {
for x == nil {}
} // ERROR "missing return"
var _ = func() int {
for x == nil {
for {
break
}
}
} // ERROR "missing return"
var _ = func() int {
for x == nil {
L:
for {
break L
}
}
} // ERROR "missing return"
var _ = func() int {
for true {}
} // ERROR "missing return"
var _ = func() int {
for true {
for {
break
}
}
} // ERROR "missing return"
var _ = func() int {
for true {
L:
for {
break L
}
}
} // ERROR "missing return"
// select in which all cases terminate and none break are okay.
var _ = func() int {
select{}
}
var _ = func() int {
select {
case <-c:
print(2)
panic("abc")
}
}
var _ = func() int {
select {
case <-c:
print(2)
for{}
}
}
var _ = func() int {
L:
select {
case <-c:
print(2)
panic("abc")
case c <- 1:
print(2)
goto L
}
}
var _ = func() int {
select {
case <-c:
print(2)
panic("abc")
default:
select{}
}
}
// if any cases don't terminate, the select isn't okay anymore
var _ = func() int {
select {
case <-c:
print(2)
}
} // ERROR "missing return"
var _ = func() int {
L:
select {
case <-c:
print(2)
panic("abc")
goto L
case c <- 1:
print(2)
}
} // ERROR "missing return"
var _ = func() int {
select {
case <-c:
print(2)
panic("abc")
default:
print(2)
}
} // ERROR "missing return"
// if any breaks refer to the select, the select isn't okay anymore, even if they're dead
var _ = func() int {
select{ default: break }
} // ERROR "missing return"
var _ = func() int {
select {
case <-c:
print(2)
panic("abc")
break
}
} // ERROR "missing return"
var _ = func() int {
L:
select {
case <-c:
print(2)
for{ break L }
}
} // ERROR "missing return"
var _ = func() int {
L:
select {
case <-c:
print(2)
panic("abc")
case c <- 1:
print(2)
break L
}
} // ERROR "missing return"
var _ = func() int {
select {
case <-c:
panic("abc")
default:
select{}
break
}
} // ERROR "missing return"
// switch with default in which all cases terminate is okay
var _ = func() int {
switch x {
case 1:
print(2)
panic(3)
default:
return 4
}
}
var _ = func() int {
switch x {
default:
return 4
case 1:
print(2)
panic(3)
}
}
var _ = func() int {
switch x {
case 1:
print(2)
fallthrough
default:
return 4
}
}
// if no default or some case doesn't terminate, switch is no longer okay
var _ = func() int {
switch {
}
} // ERROR "missing return"
var _ = func() int {
switch x {
case 1:
print(2)
panic(3)
case 2:
return 4
}
} // ERROR "missing return"
var _ = func() int {
switch x {
case 2:
return 4
case 1:
print(2)
panic(3)
}
} // ERROR "missing return"
var _ = func() int {
switch x {
case 1:
print(2)
fallthrough
case 2:
return 4
}
} // ERROR "missing return"
var _ = func() int {
switch x {
case 1:
print(2)
panic(3)
}
} // ERROR "missing return"
// if any breaks refer to the switch, switch is no longer okay
var _ = func() int {
L:
switch x {
case 1:
print(2)
panic(3)
break L
default:
return 4
}
} // ERROR "missing return"
var _ = func() int {
switch x {
default:
return 4
break
case 1:
print(2)
panic(3)
}
} // ERROR "missing return"
var _ = func() int {
L:
switch x {
case 1:
print(2)
for {
break L
}
default:
return 4
}
} // ERROR "missing return"
// type switch with default in which all cases terminate is okay
var _ = func() int {
switch x.(type) {
case int:
print(2)
panic(3)
default:
return 4
}
}
var _ = func() int {
switch x.(type) {
default:
return 4
case int:
print(2)
panic(3)
}
}
// if no default or some case doesn't terminate, switch is no longer okay
var _ = func() int {
switch {
}
} // ERROR "missing return"
var _ = func() int {
switch x.(type) {
case int:
print(2)
panic(3)
case float64:
return 4
}
} // ERROR "missing return"
var _ = func() int {
switch x.(type) {
case float64:
return 4
case int:
print(2)
panic(3)
}
} // ERROR "missing return"
var _ = func() int {
switch x.(type) {
case int:
print(2)
panic(3)
}
} // ERROR "missing return"
// if any breaks refer to the switch, switch is no longer okay
var _ = func() int {
L:
switch x.(type) {
case int:
print(2)
panic(3)
break L
default:
return 4
}
} // ERROR "missing return"
var _ = func() int {
switch x.(type) {
default:
return 4
break
case int:
print(2)
panic(3)
}
} // ERROR "missing return"
var _ = func() int {
L:
switch x.(type) {
case int:
print(2)
for {
break L
}
default:
return 4
}
} // ERROR "missing return"
var _ = func() int {
switch x.(type) {
default:
return 4
case int, float64:
print(2)
panic(3)
}
}
/**/
// $G $D/$F.go && $L $F.$A && // skip
// ./$A.out >tmp.go && $G tmp.go && $L -o $A.out1 tmp.$A && ./$A.out1
// rm -f tmp.go $A.out1
// NOTE: This test is not run by 'run.go' and so not run by all.bash. // NOTE: the actual tests to run are rotate[0123].go
// To run this test you must use the ./run shell script.
// Copyright 2012 The Go Authors. All rights reserved. // Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
...@@ -12,8 +9,8 @@ ...@@ -12,8 +9,8 @@
// Generate test of shift and rotate by constants. // Generate test of shift and rotate by constants.
// The output is compiled and run. // The output is compiled and run.
// //
// The output takes around a gigabyte of memory to compile, link, and run // The integer type depends on the value of mode (rotate direction,
// but it is only done during ./run, not in normal builds using run.go. // signedness).
package main package main
...@@ -37,9 +34,7 @@ func main() { ...@@ -37,9 +34,7 @@ func main() {
typ := fmt.Sprintf("int%d", 1<<logBits) typ := fmt.Sprintf("int%d", 1<<logBits)
fmt.Fprint(b, strings.Replace(checkFunc, "XXX", typ, -1)) fmt.Fprint(b, strings.Replace(checkFunc, "XXX", typ, -1))
fmt.Fprint(b, strings.Replace(checkFunc, "XXX", "u"+typ, -1)) fmt.Fprint(b, strings.Replace(checkFunc, "XXX", "u"+typ, -1))
for mode := 0; mode < 1<<2; mode++ { gentest(b, 1<<logBits, mode&1 != 0, mode&2 != 0)
gentest(b, 1<<logBits, mode&1 != 0, mode&2 != 0)
}
} }
} }
......
// runoutput ./rotate.go
// Copyright 2013 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.
// Generate test of bit rotations.
// The output is compiled and run.
package main
const mode = 0
// runoutput ./rotate.go
// Copyright 2013 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.
// Generate test of bit rotations.
// The output is compiled and run.
package main
const mode = 1
// runoutput ./rotate.go
// Copyright 2013 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.
// Generate test of bit rotations.
// The output is compiled and run.
package main
const mode = 2
// runoutput ./rotate.go
// Copyright 2013 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.
// Generate test of bit rotations.
// The output is compiled and run.
package main
const mode = 3
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Run runs tests in the test directory. // Run runs tests in the test directory.
// //
// TODO(bradfitz): docs of some sort, once we figure out how we're changing // TODO(bradfitz): docs of some sort, once we figure out how we're changing
// headers of files // headers of files
package main package main
...@@ -30,10 +30,11 @@ import ( ...@@ -30,10 +30,11 @@ import (
) )
var ( var (
verbose = flag.Bool("v", false, "verbose. if set, parallelism is set to 1.") verbose = flag.Bool("v", false, "verbose. if set, parallelism is set to 1.")
numParallel = flag.Int("n", runtime.NumCPU(), "number of parallel tests to run") numParallel = flag.Int("n", runtime.NumCPU(), "number of parallel tests to run")
summary = flag.Bool("summary", false, "show summary of results") summary = flag.Bool("summary", false, "show summary of results")
showSkips = flag.Bool("show_skips", false, "show skipped tests") showSkips = flag.Bool("show_skips", false, "show skipped tests")
runoutputLimit = flag.Int("l", defaultRunOutputLimit(), "number of parallel runoutput tests to run")
) )
var ( var (
...@@ -53,6 +54,10 @@ var ( ...@@ -53,6 +54,10 @@ var (
// toRun is the channel of tests to run. // toRun is the channel of tests to run.
// It is nil until the first test is started. // It is nil until the first test is started.
toRun chan *test toRun chan *test
// rungatec controls the max number of runoutput tests
// executed in parallel as they can each consume a lot of memory.
rungatec chan bool
) )
// maxTests is an upper bound on the total number of tests. // maxTests is an upper bound on the total number of tests.
...@@ -68,6 +73,7 @@ func main() { ...@@ -68,6 +73,7 @@ func main() {
} }
ratec = make(chan bool, *numParallel) ratec = make(chan bool, *numParallel)
rungatec = make(chan bool, *runoutputLimit)
var err error var err error
letter, err = build.ArchChar(build.Default.GOARCH) letter, err = build.ArchChar(build.Default.GOARCH)
check(err) check(err)
...@@ -128,7 +134,7 @@ func main() { ...@@ -128,7 +134,7 @@ func main() {
if !*verbose && test.err == nil { if !*verbose && test.err == nil {
continue continue
} }
fmt.Printf("%-10s %-20s: %s\n", test.action, test.goFileName(), errStr) fmt.Printf("%-20s %-20s: %s\n", test.action, test.goFileName(), errStr)
} }
if *summary { if *summary {
...@@ -165,6 +171,26 @@ func goFiles(dir string) []string { ...@@ -165,6 +171,26 @@ func goFiles(dir string) []string {
return names return names
} }
type runCmd func(...string) ([]byte, error)
func compileFile(runcmd runCmd, longname string) (out []byte, err error) {
return runcmd("go", "tool", gc, "-e", longname)
}
func compileInDir(runcmd runCmd, dir string, names ...string) (out []byte, err error) {
cmd := []string{"go", "tool", gc, "-e", "-D", ".", "-I", "."}
for _, name := range names {
cmd = append(cmd, filepath.Join(dir, name))
}
return runcmd(cmd...)
}
func linkFile(runcmd runCmd, goname string) (err error) {
pfile := strings.Replace(goname, ".go", "."+letter, -1)
_, err = runcmd("go", "tool", ld, "-o", "a.exe", "-L", ".", pfile)
return
}
// skipError describes why a test was skipped. // skipError describes why a test was skipped.
type skipError string type skipError string
...@@ -182,13 +208,13 @@ type test struct { ...@@ -182,13 +208,13 @@ type test struct {
donec chan bool // closed when done donec chan bool // closed when done
src string src string
action string // "compile", "build", "run", "errorcheck", "skip", "runoutput", "compiledir" action string // "compile", "build", etc.
tempDir string tempDir string
err error err error
} }
// startTest // startTest
func startTest(dir, gofile string) *test { func startTest(dir, gofile string) *test {
t := &test{ t := &test{
dir: dir, dir: dir,
...@@ -230,6 +256,93 @@ func (t *test) goDirName() string { ...@@ -230,6 +256,93 @@ func (t *test) goDirName() string {
return filepath.Join(t.dir, strings.Replace(t.gofile, ".go", ".dir", -1)) return filepath.Join(t.dir, strings.Replace(t.gofile, ".go", ".dir", -1))
} }
func goDirFiles(longdir string) (filter []os.FileInfo, err error) {
files, dirErr := ioutil.ReadDir(longdir)
if dirErr != nil {
return nil, dirErr
}
for _, gofile := range files {
if filepath.Ext(gofile.Name()) == ".go" {
filter = append(filter, gofile)
}
}
return
}
var packageRE = regexp.MustCompile(`(?m)^package (\w+)`)
func goDirPackages(longdir string) ([][]string, error) {
files, err := goDirFiles(longdir)
if err != nil {
return nil, err
}
var pkgs [][]string
m := make(map[string]int)
for _, file := range files {
name := file.Name()
data, err := ioutil.ReadFile(filepath.Join(longdir, name))
if err != nil {
return nil, err
}
pkgname := packageRE.FindStringSubmatch(string(data))
if pkgname == nil {
return nil, fmt.Errorf("cannot find package name in %s", name)
}
i, ok := m[pkgname[1]]
if !ok {
i = len(pkgs)
pkgs = append(pkgs, nil)
m[pkgname[1]] = i
}
pkgs[i] = append(pkgs[i], name)
}
return pkgs, nil
}
// shouldTest looks for build tags in a source file and returns
// whether the file should be used according to the tags.
func shouldTest(src string, goos, goarch string) (ok bool, whyNot string) {
if idx := strings.Index(src, "\npackage"); idx >= 0 {
src = src[:idx]
}
notgoos := "!" + goos
notgoarch := "!" + goarch
for _, line := range strings.Split(src, "\n") {
line = strings.TrimSpace(line)
if strings.HasPrefix(line, "//") {
line = line[2:]
} else {
continue
}
line = strings.TrimSpace(line)
if len(line) == 0 || line[0] != '+' {
continue
}
words := strings.Fields(line)
if words[0] == "+build" {
for _, word := range words {
switch word {
case goos, goarch:
return true, ""
case notgoos, notgoarch:
continue
default:
if word[0] == '!' {
// NOT something-else
return true, ""
}
}
}
// no matching tag found.
return false, line
}
}
// no build tags.
return true, ""
}
func init() { checkShouldTest() }
// run runs a test. // run runs a test.
func (t *test) run() { func (t *test) run() {
defer close(t.donec) defer close(t.donec)
...@@ -249,7 +362,18 @@ func (t *test) run() { ...@@ -249,7 +362,18 @@ func (t *test) run() {
t.err = errors.New("double newline not found") t.err = errors.New("double newline not found")
return return
} }
if ok, why := shouldTest(t.src, runtime.GOOS, runtime.GOARCH); !ok {
t.action = "skip"
if *showSkips {
fmt.Printf("%-20s %-20s: %s\n", t.action, t.goFileName(), why)
}
return
}
action := t.src[:pos] action := t.src[:pos]
if nl := strings.Index(action, "\n"); nl >= 0 && strings.Contains(action[:nl], "+build") {
// skip first line
action = action[nl+1:]
}
if strings.HasPrefix(action, "//") { if strings.HasPrefix(action, "//") {
action = action[2:] action = action[2:]
} }
...@@ -263,12 +387,15 @@ func (t *test) run() { ...@@ -263,12 +387,15 @@ func (t *test) run() {
} }
switch action { switch action {
case "rundircmpout":
action = "rundir"
t.action = "rundir"
case "cmpout": case "cmpout":
action = "run" // the run case already looks for <dir>/<test>.out files action = "run" // the run case already looks for <dir>/<test>.out files
fallthrough fallthrough
case "compile", "compiledir", "build", "run", "runoutput": case "compile", "compiledir", "build", "run", "runoutput", "rundir":
t.action = action t.action = action
case "errorcheck": case "errorcheck", "errorcheckdir", "errorcheckoutput":
t.action = action t.action = action
wantError = true wantError = true
for len(args) > 0 && strings.HasPrefix(args[0], "-") { for len(args) > 0 && strings.HasPrefix(args[0], "-") {
...@@ -306,8 +433,12 @@ func (t *test) run() { ...@@ -306,8 +433,12 @@ func (t *test) run() {
cmd.Stderr = &buf cmd.Stderr = &buf
if useTmp { if useTmp {
cmd.Dir = t.tempDir cmd.Dir = t.tempDir
cmd.Env = envForDir(cmd.Dir)
} }
err := cmd.Run() err := cmd.Run()
if err != nil {
err = fmt.Errorf("%s\n%s", err, buf.Bytes())
}
return buf.Bytes(), err return buf.Bytes(), err
} }
...@@ -328,7 +459,7 @@ func (t *test) run() { ...@@ -328,7 +459,7 @@ func (t *test) run() {
} }
} else { } else {
if err != nil { if err != nil {
t.err = fmt.Errorf("%s\n%s", err, out) t.err = err
return return
} }
} }
...@@ -336,66 +467,156 @@ func (t *test) run() { ...@@ -336,66 +467,156 @@ func (t *test) run() {
return return
case "compile": case "compile":
out, err := runcmd("go", "tool", gc, "-e", "-o", "a."+letter, long) _, t.err = compileFile(runcmd, long)
if err != nil {
t.err = fmt.Errorf("%s\n%s", err, out)
}
case "compiledir": case "compiledir":
// Compile all files in the directory in lexicographic order. // Compile all files in the directory in lexicographic order.
longdir := filepath.Join(cwd, t.goDirName()) longdir := filepath.Join(cwd, t.goDirName())
files, dirErr := ioutil.ReadDir(longdir) pkgs, err := goDirPackages(longdir)
if dirErr != nil { if err != nil {
t.err = dirErr t.err = err
return return
} }
for _, gofile := range files { for _, gofiles := range pkgs {
if filepath.Ext(gofile.Name()) != ".go" { _, t.err = compileInDir(runcmd, longdir, gofiles...)
continue if t.err != nil {
return
} }
afile := strings.Replace(gofile.Name(), ".go", "."+letter, -1) }
out, err := runcmd("go", "tool", gc, "-e", "-D.", "-I.", "-o", afile, filepath.Join(longdir, gofile.Name()))
if err != nil { case "errorcheckdir":
t.err = fmt.Errorf("%s\n%s", err, out) // errorcheck all files in lexicographic order
// useful for finding importing errors
longdir := filepath.Join(cwd, t.goDirName())
pkgs, err := goDirPackages(longdir)
if err != nil {
t.err = err
return
}
for i, gofiles := range pkgs {
out, err := compileInDir(runcmd, longdir, gofiles...)
if i == len(pkgs)-1 {
if wantError && err == nil {
t.err = fmt.Errorf("compilation succeeded unexpectedly\n%s", out)
return
} else if !wantError && err != nil {
t.err = err
return
}
} else if err != nil {
t.err = err
return
}
var fullshort []string
for _, name := range gofiles {
fullshort = append(fullshort, filepath.Join(longdir, name), name)
}
t.err = t.errorCheck(string(out), fullshort...)
if t.err != nil {
break break
} }
} }
case "rundir":
// Compile all files in the directory in lexicographic order.
// then link as if the last file is the main package and run it
longdir := filepath.Join(cwd, t.goDirName())
pkgs, err := goDirPackages(longdir)
if err != nil {
t.err = err
return
}
for i, gofiles := range pkgs {
_, err := compileInDir(runcmd, longdir, gofiles...)
if err != nil {
t.err = err
return
}
if i == len(pkgs)-1 {
err = linkFile(runcmd, gofiles[0])
if err != nil {
t.err = err
return
}
out, err := runcmd(append([]string{filepath.Join(t.tempDir, "a.exe")}, args...)...)
if err != nil {
t.err = err
return
}
if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() {
t.err = fmt.Errorf("incorrect output\n%s", out)
}
}
}
case "build": case "build":
out, err := runcmd("go", "build", "-o", "a.exe", long) _, err := runcmd("go", "build", "-o", "a.exe", long)
if err != nil { if err != nil {
t.err = fmt.Errorf("%s\n%s", err, out) t.err = err
} }
case "run": case "run":
useTmp = false useTmp = false
out, err := runcmd(append([]string{"go", "run", t.goFileName()}, args...)...) out, err := runcmd(append([]string{"go", "run", t.goFileName()}, args...)...)
if err != nil { if err != nil {
t.err = fmt.Errorf("%s\n%s", err, out) t.err = err
} }
if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() { if strings.Replace(string(out), "\r\n", "\n", -1) != t.expectedOutput() {
t.err = fmt.Errorf("incorrect output\n%s", out) t.err = fmt.Errorf("incorrect output\n%s", out)
} }
case "runoutput": case "runoutput":
rungatec <- true
defer func() {
<-rungatec
}()
useTmp = false useTmp = false
out, err := runcmd("go", "run", t.goFileName()) out, err := runcmd(append([]string{"go", "run", t.goFileName()}, args...)...)
if err != nil { if err != nil {
t.err = fmt.Errorf("%s\n%s", err, out) t.err = err
} }
tfile := filepath.Join(t.tempDir, "tmp__.go") tfile := filepath.Join(t.tempDir, "tmp__.go")
err = ioutil.WriteFile(tfile, out, 0666) if err := ioutil.WriteFile(tfile, out, 0666); err != nil {
if err != nil {
t.err = fmt.Errorf("write tempfile:%s", err) t.err = fmt.Errorf("write tempfile:%s", err)
return return
} }
out, err = runcmd("go", "run", tfile) out, err = runcmd("go", "run", tfile)
if err != nil { if err != nil {
t.err = fmt.Errorf("%s\n%s", err, out) t.err = err
} }
if string(out) != t.expectedOutput() { if string(out) != t.expectedOutput() {
t.err = fmt.Errorf("incorrect output\n%s", out) t.err = fmt.Errorf("incorrect output\n%s", out)
} }
case "errorcheckoutput":
useTmp = false
out, err := runcmd(append([]string{"go", "run", t.goFileName()}, args...)...)
if err != nil {
t.err = err
}
tfile := filepath.Join(t.tempDir, "tmp__.go")
err = ioutil.WriteFile(tfile, out, 0666)
if err != nil {
t.err = fmt.Errorf("write tempfile:%s", err)
return
}
cmdline := []string{"go", "tool", gc, "-e", "-o", "a." + letter}
cmdline = append(cmdline, flags...)
cmdline = append(cmdline, tfile)
out, err = runcmd(cmdline...)
if wantError {
if err == nil {
t.err = fmt.Errorf("compilation succeeded unexpectedly\n%s", out)
return
}
} else {
if err != nil {
t.err = err
return
}
}
t.err = t.errorCheck(string(out), tfile, "tmp__.go")
return
} }
} }
...@@ -417,7 +638,7 @@ func (t *test) expectedOutput() string { ...@@ -417,7 +638,7 @@ func (t *test) expectedOutput() string {
return string(b) return string(b)
} }
func (t *test) errorCheck(outStr string, full, short string) (err error) { func (t *test) errorCheck(outStr string, fullshort ...string) (err error) {
defer func() { defer func() {
if *verbose && err != nil { if *verbose && err != nil {
log.Printf("%s gc output:\n%s", t, outStr) log.Printf("%s gc output:\n%s", t, outStr)
...@@ -434,17 +655,28 @@ func (t *test) errorCheck(outStr string, full, short string) (err error) { ...@@ -434,17 +655,28 @@ func (t *test) errorCheck(outStr string, full, short string) (err error) {
} }
if strings.HasPrefix(line, "\t") { if strings.HasPrefix(line, "\t") {
out[len(out)-1] += "\n" + line out[len(out)-1] += "\n" + line
} else { } else if strings.HasPrefix(line, "go tool") {
continue
} else if strings.TrimSpace(line) != "" {
out = append(out, line) out = append(out, line)
} }
} }
// Cut directory name. // Cut directory name.
for i := range out { for i := range out {
out[i] = strings.Replace(out[i], full, short, -1) for j := 0; j < len(fullshort); j += 2 {
full, short := fullshort[j], fullshort[j+1]
out[i] = strings.Replace(out[i], full, short, -1)
}
} }
for _, we := range t.wantedErrors() { var want []wantedError
for j := 0; j < len(fullshort); j += 2 {
full, short := fullshort[j], fullshort[j+1]
want = append(want, t.wantedErrors(full, short)...)
}
for _, we := range want {
var errmsgs []string var errmsgs []string
errmsgs, out = partitionStrings(we.filterRe, out) errmsgs, out = partitionStrings(we.filterRe, out)
if len(errmsgs) == 0 { if len(errmsgs) == 0 {
...@@ -452,6 +684,7 @@ func (t *test) errorCheck(outStr string, full, short string) (err error) { ...@@ -452,6 +684,7 @@ func (t *test) errorCheck(outStr string, full, short string) (err error) {
continue continue
} }
matched := false matched := false
n := len(out)
for _, errmsg := range errmsgs { for _, errmsg := range errmsgs {
if we.re.MatchString(errmsg) { if we.re.MatchString(errmsg) {
matched = true matched = true
...@@ -460,11 +693,18 @@ func (t *test) errorCheck(outStr string, full, short string) (err error) { ...@@ -460,11 +693,18 @@ func (t *test) errorCheck(outStr string, full, short string) (err error) {
} }
} }
if !matched { if !matched {
errs = append(errs, fmt.Errorf("%s:%d: no match for %q in%s", we.file, we.lineNum, we.reStr, strings.Join(out, "\n"))) errs = append(errs, fmt.Errorf("%s:%d: no match for %#q in:\n\t%s", we.file, we.lineNum, we.reStr, strings.Join(out[n:], "\n\t")))
continue continue
} }
} }
if len(out) > 0 {
errs = append(errs, fmt.Errorf("Unmatched Errors:"))
for _, errLine := range out {
errs = append(errs, fmt.Errorf("%s", errLine))
}
}
if len(errs) == 0 { if len(errs) == 0 {
return nil return nil
} }
...@@ -505,8 +745,9 @@ var ( ...@@ -505,8 +745,9 @@ var (
lineRx = regexp.MustCompile(`LINE(([+-])([0-9]+))?`) lineRx = regexp.MustCompile(`LINE(([+-])([0-9]+))?`)
) )
func (t *test) wantedErrors() (errs []wantedError) { func (t *test) wantedErrors(file, short string) (errs []wantedError) {
for i, line := range strings.Split(t.src, "\n") { src, _ := ioutil.ReadFile(file)
for i, line := range strings.Split(string(src), "\n") {
lineNum := i + 1 lineNum := i + 1
if strings.Contains(line, "////") { if strings.Contains(line, "////") {
// double comment disables ERROR // double comment disables ERROR
...@@ -519,7 +760,7 @@ func (t *test) wantedErrors() (errs []wantedError) { ...@@ -519,7 +760,7 @@ func (t *test) wantedErrors() (errs []wantedError) {
all := m[1] all := m[1]
mm := errQuotesRx.FindAllStringSubmatch(all, -1) mm := errQuotesRx.FindAllStringSubmatch(all, -1)
if mm == nil { if mm == nil {
log.Fatalf("invalid errchk line in %s: %s", t.goFileName(), line) log.Fatalf("%s:%d: invalid errchk line: %s", t.goFileName(), lineNum, line)
} }
for _, m := range mm { for _, m := range mm {
rx := lineRx.ReplaceAllStringFunc(m[1], func(m string) string { rx := lineRx.ReplaceAllStringFunc(m[1], func(m string) string {
...@@ -531,15 +772,19 @@ func (t *test) wantedErrors() (errs []wantedError) { ...@@ -531,15 +772,19 @@ func (t *test) wantedErrors() (errs []wantedError) {
delta, _ := strconv.Atoi(m[5:]) delta, _ := strconv.Atoi(m[5:])
n -= delta n -= delta
} }
return fmt.Sprintf("%s:%d", t.gofile, n) return fmt.Sprintf("%s:%d", short, n)
}) })
filterPattern := fmt.Sprintf(`^(\w+/)?%s:%d[:[]`, t.gofile, lineNum) re, err := regexp.Compile(rx)
if err != nil {
log.Fatalf("%s:%d: invalid regexp in ERROR line: %v", t.goFileName(), lineNum, err)
}
filterPattern := fmt.Sprintf(`^(\w+/)?%s:%d[:[]`, regexp.QuoteMeta(short), lineNum)
errs = append(errs, wantedError{ errs = append(errs, wantedError{
reStr: rx, reStr: rx,
re: regexp.MustCompile(rx), re: re,
filterRe: regexp.MustCompile(filterPattern), filterRe: regexp.MustCompile(filterPattern),
lineNum: lineNum, lineNum: lineNum,
file: t.gofile, file: short,
}) })
} }
} }
...@@ -548,60 +793,56 @@ func (t *test) wantedErrors() (errs []wantedError) { ...@@ -548,60 +793,56 @@ func (t *test) wantedErrors() (errs []wantedError) {
} }
var skipOkay = map[string]bool{ var skipOkay = map[string]bool{
"args.go": true, "linkx.go": true, // like "run" but wants linker flags
"ddd3.go": true, "sinit.go": true,
"import3.go": true, "fixedbugs/bug248.go": true, // combines errorcheckdir and rundir in the same dir.
"import4.go": true, "fixedbugs/bug302.go": true, // tests both .$O and .a imports.
"index.go": true, "fixedbugs/bug345.go": true, // needs the appropriate flags in gc invocation.
"linkx.go": true, "fixedbugs/bug369.go": true, // needs compiler flags.
"method4.go": true, "fixedbugs/bug429.go": true, // like "run" but program should fail
"nul1.go": true, "bugs/bug395.go": true,
"rotate.go": true, }
"sigchld.go": true,
"sinit.go": true, // defaultRunOutputLimit returns the number of runoutput tests that
"interface/embed1.go": true, // can be executed in parallel.
"interface/private.go": true, func defaultRunOutputLimit() int {
"interface/recursive2.go": true, const maxArmCPU = 2
"dwarf/main.go": true,
"dwarf/z1.go": true, cpu := runtime.NumCPU()
"dwarf/z10.go": true, if runtime.GOARCH == "arm" && cpu > maxArmCPU {
"dwarf/z11.go": true, cpu = maxArmCPU
"dwarf/z12.go": true, }
"dwarf/z13.go": true, return cpu
"dwarf/z14.go": true, }
"dwarf/z15.go": true,
"dwarf/z16.go": true, // checkShouldTest runs canity checks on the shouldTest function.
"dwarf/z17.go": true, func checkShouldTest() {
"dwarf/z18.go": true, assert := func(ok bool, _ string) {
"dwarf/z19.go": true, if !ok {
"dwarf/z2.go": true, panic("fail")
"dwarf/z20.go": true, }
"dwarf/z3.go": true, }
"dwarf/z4.go": true, assertNot := func(ok bool, _ string) { assert(!ok, "") }
"dwarf/z5.go": true, assert(shouldTest("// +build linux", "linux", "arm"))
"dwarf/z6.go": true, assert(shouldTest("// +build !windows", "linux", "arm"))
"dwarf/z7.go": true, assertNot(shouldTest("// +build !windows", "windows", "amd64"))
"dwarf/z8.go": true, assertNot(shouldTest("// +build arm 386", "linux", "amd64"))
"dwarf/z9.go": true, assert(shouldTest("// This is a test.", "os", "arch"))
"fixedbugs/bug083.go": true, }
"fixedbugs/bug133.go": true,
"fixedbugs/bug160.go": true, // envForDir returns a copy of the environment
"fixedbugs/bug191.go": true, // suitable for running in the given directory.
"fixedbugs/bug248.go": true, // The environment is the current process's environment
"fixedbugs/bug302.go": true, // but with an updated $PWD, so that an os.Getwd in the
"fixedbugs/bug313.go": true, // child will be faster.
"fixedbugs/bug322.go": true, func envForDir(dir string) []string {
"fixedbugs/bug324.go": true, env := os.Environ()
"fixedbugs/bug345.go": true, for i, kv := range env {
"fixedbugs/bug367.go": true, if strings.HasPrefix(kv, "PWD=") {
"fixedbugs/bug369.go": true, env[i] = "PWD=" + dir
"fixedbugs/bug382.go": true, return env
"fixedbugs/bug385_32.go": true, }
"fixedbugs/bug385_64.go": true, }
"fixedbugs/bug414.go": true, env = append(env, "PWD="+dir)
"fixedbugs/bug424.go": true, return env
"fixedbugs/bug429.go": true,
"fixedbugs/bug437.go": true,
"bugs/bug395.go": true,
"bugs/bug434.go": true,
} }
// $G $D/pkg.go && pack grc pkg.a pkg.$A 2> /dev/null && rm pkg.$A && errchk $G -I. -u $D/main.go // $G $D/pkg.go && pack grc pkg.a pkg.$A 2> /dev/null && rm pkg.$A && errchk $G -I . -u $D/main.go
// rm -f pkg.a // rm -f pkg.a
// Copyright 2012 The Go Authors. All rights reserved. // Copyright 2012 The Go Authors. All rights reserved.
......
// $G $D/pkg.go && pack grcS pkg.a pkg.$A 2> /dev/null && rm pkg.$A && $G -I. -u $D/main.go // $G $D/pkg.go && pack grcS pkg.a pkg.$A 2> /dev/null && rm pkg.$A && $G -I . -u $D/main.go
// rm -f pkg.a // rm -f pkg.a
// Copyright 2012 The Go Authors. All rights reserved. // Copyright 2012 The Go Authors. All rights reserved.
......
// [ "$GOOS" == windows ] || // +build !windows
// ($G $D/$F.go && $L $F.$A && ./$A.out 2>&1 | cmp - $D/$F.out) // cmpout
// NOTE: This test is not run by 'run.go' and so not run by all.bash.
// To run this test you must use the ./run shell script.
// Copyright 2009 The Go Authors. All rights reserved. // Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
......
...@@ -259,3 +259,13 @@ var copy_pt0a = pt0a ...@@ -259,3 +259,13 @@ var copy_pt0a = pt0a
var copy_pt0b = pt0b var copy_pt0b = pt0b
var copy_pt1 = pt1 var copy_pt1 = pt1
var copy_pt1a = pt1a var copy_pt1a = pt1a
var _ interface{} = 1
type T1 int
func (t *T1) M() {}
type Mer interface { M() }
var _ Mer = (*T1)(nil)
...@@ -4,8 +4,6 @@ ...@@ -4,8 +4,6 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// Test unsafe.Sizeof, unsafe.Alignof, and unsafe.Offsetof all return uintptr.
package main package main
import "unsafe" import "unsafe"
...@@ -18,8 +16,143 @@ var t T ...@@ -18,8 +16,143 @@ var t T
func isUintptr(uintptr) {} func isUintptr(uintptr) {}
type T2 struct {
A int32
U2
}
type U2 struct {
B int32
C int32
}
var t2 T2
var p2 *T2
func main() { func main() {
// Test unsafe.Sizeof, unsafe.Alignof, and unsafe.Offsetof all return uintptr.
isUintptr(unsafe.Sizeof(t)) isUintptr(unsafe.Sizeof(t))
isUintptr(unsafe.Alignof(t)) isUintptr(unsafe.Alignof(t))
isUintptr(unsafe.Offsetof(t.X)) isUintptr(unsafe.Offsetof(t.X))
// Test correctness of Offsetof with respect to embedded fields (issue 4909).
if unsafe.Offsetof(t2.C) != 8 {
println(unsafe.Offsetof(t2.C), "!= 8")
panic("unsafe.Offsetof(t2.C) != 8")
}
if unsafe.Offsetof(p2.C) != 8 {
println(unsafe.Offsetof(p2.C), "!= 8")
panic("unsafe.Offsetof(p2.C) != 8")
}
if unsafe.Offsetof(t2.U2.C) != 4 {
println(unsafe.Offsetof(t2.U2.C), "!= 4")
panic("unsafe.Offsetof(t2.U2.C) != 4")
}
if unsafe.Offsetof(p2.U2.C) != 4 {
println(unsafe.Offsetof(p2.U2.C), "!= 4")
panic("unsafe.Offsetof(p2.U2.C) != 4")
}
testDeep()
testNotEmbedded()
}
type (
S1 struct {
A int32
S2
}
S2 struct {
B int32
S3
}
S3 struct {
C int32
S4
}
S4 struct {
D int32
S5
}
S5 struct {
E int32
S6
}
S6 struct {
F int32
S7
}
S7 struct {
G int32
S8
}
S8 struct {
H int32
*S1
}
)
func testDeep() {
var s1 S1
switch {
case unsafe.Offsetof(s1.A) != 0:
panic("unsafe.Offsetof(s1.A) != 0")
case unsafe.Offsetof(s1.B) != 4:
panic("unsafe.Offsetof(s1.B) != 4")
case unsafe.Offsetof(s1.C) != 8:
panic("unsafe.Offsetof(s1.C) != 8")
case unsafe.Offsetof(s1.D) != 12:
panic("unsafe.Offsetof(s1.D) != 12")
case unsafe.Offsetof(s1.E) != 16:
panic("unsafe.Offsetof(s1.E) != 16")
case unsafe.Offsetof(s1.F) != 20:
panic("unsafe.Offsetof(s1.F) != 20")
case unsafe.Offsetof(s1.G) != 24:
panic("unsafe.Offsetof(s1.G) != 24")
case unsafe.Offsetof(s1.H) != 28:
panic("unsafe.Offsetof(s1.H) != 28")
case unsafe.Offsetof(s1.S1) != 32:
panic("unsafe.Offsetof(s1.S1) != 32")
case unsafe.Offsetof(s1.S1.S2.S3.S4.S5.S6.S7.S8.S1.S2) != 4:
panic("unsafe.Offsetof(s1.S1.S2.S3.S4.S5.S6.S7.S8.S1.S2) != 4")
}
}
func testNotEmbedded() {
type T2 struct {
B int32
C int32
}
type T1 struct {
A int32
T2
}
type T struct {
Dummy int32
F T1
P *T1
}
var t T
var p *T
switch {
case unsafe.Offsetof(t.F.B) != 4:
panic("unsafe.Offsetof(t.F.B) != 4")
case unsafe.Offsetof(t.F.C) != 8:
panic("unsafe.Offsetof(t.F.C) != 8")
case unsafe.Offsetof(t.P.B) != 4:
panic("unsafe.Offsetof(t.P.B) != 4")
case unsafe.Offsetof(t.P.C) != 8:
panic("unsafe.Offsetof(t.P.C) != 8")
case unsafe.Offsetof(p.F.B) != 4:
panic("unsafe.Offsetof(p.F.B) != 4")
case unsafe.Offsetof(p.F.C) != 8:
panic("unsafe.Offsetof(p.F.C) != 8")
case unsafe.Offsetof(p.P.B) != 4:
panic("unsafe.Offsetof(p.P.B) != 4")
case unsafe.Offsetof(p.P.C) != 8:
panic("unsafe.Offsetof(p.P.C) != 8")
}
} }
// Copyright 2013 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 main
import (
"math/rand"
"runtime"
"sync"
)
func mapTypes() []MapType {
// TODO(bradfitz): bunch more map types of all different key and value types.
// Use reflect.MapOf and a program to generate lots of types & struct types.
// For now, just one:
return []MapType{intMapType{}}
}
type MapType interface {
NewMap() Map
}
type Map interface {
AddItem()
DelItem()
Len() int
GetItem()
RangeAll()
}
func stressMapType(mt MapType, done func()) {
defer done()
m := mt.NewMap()
for m.Len() < 10000 {
Println("map at ", m.Len())
if m.Len()%100 == 0 {
runtime.Gosched()
}
m.AddItem()
m.AddItem()
m.DelItem()
var wg sync.WaitGroup
const numGets = 10
wg.Add(numGets)
for i := 0; i < numGets; i++ {
go func(i int) {
if i&1 == 0 {
m.GetItem()
} else {
m.RangeAll()
}
wg.Done()
}(i)
}
wg.Wait()
}
for m.Len() > 0 {
m.DelItem()
}
}
type intMapType struct{}
func (intMapType) NewMap() Map {
return make(intMap)
}
var deadcafe = []byte("\xDE\xAD\xCA\xFE")
type intMap map[int][]byte
func (m intMap) AddItem() {
s0 := len(m)
for len(m) == s0 {
key := rand.Intn(s0 + 1)
m[key] = make([]byte, rand.Intn(64<<10))
}
}
func (m intMap) DelItem() {
for k := range m {
delete(m, k)
return
}
}
func (m intMap) GetItem() {
key := rand.Intn(len(m))
if s, ok := m[key]; ok {
copy(s, deadcafe)
}
}
func (m intMap) Len() int { return len(m) }
func (m intMap) RangeAll() {
for _ = range m {
}
}
func stressMaps() {
for {
var wg sync.WaitGroup
for _, mt := range mapTypes() {
wg.Add(1)
go stressMapType(mt, wg.Done)
}
wg.Wait()
}
}
// Copyright 2013 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 main
import (
"go/ast"
"go/parser"
"go/token"
"os"
"path"
"runtime"
"strings"
)
func isGoFile(dir os.FileInfo) bool {
return !dir.IsDir() &&
!strings.HasPrefix(dir.Name(), ".") && // ignore .files
path.Ext(dir.Name()) == ".go"
}
func isPkgFile(dir os.FileInfo) bool {
return isGoFile(dir) &&
!strings.HasSuffix(dir.Name(), "_test.go") // ignore test files
}
func pkgName(filename string) string {
file, err := parser.ParseFile(token.NewFileSet(), filename, nil, parser.PackageClauseOnly)
if err != nil || file == nil {
return ""
}
return file.Name.Name
}
func parseDir(dirpath string) map[string]*ast.Package {
// the package name is the directory name within its parent.
// (use dirname instead of path because dirname is clean; it
// has no trailing '/')
_, pkgname := path.Split(dirpath)
// filter function to select the desired .go files
filter := func(d os.FileInfo) bool {
if isPkgFile(d) {
// Some directories contain main packages: Only accept
// files that belong to the expected package so that
// parser.ParsePackage doesn't return "multiple packages
// found" errors.
// Additionally, accept the special package name
// fakePkgName if we are looking at cmd documentation.
name := pkgName(dirpath + "/" + d.Name())
return name == pkgname
}
return false
}
// get package AST
pkgs, err := parser.ParseDir(token.NewFileSet(), dirpath, filter, parser.ParseComments)
if err != nil {
println("parse", dirpath, err.Error())
panic("go ParseDir fail: " + err.Error())
}
return pkgs
}
func stressParseGo() {
pkgroot := runtime.GOROOT() + "/src/pkg/"
for {
m := make(map[string]map[string]*ast.Package)
for _, pkg := range packages {
m[pkg] = parseDir(pkgroot + pkg)
Println("parsed go package", pkg)
}
}
}
// find . -type d -not -path "./exp" -not -path "./exp/*" -printf "\t\"%p\",\n" | sort | sed "s/\.\///" | grep -v testdata
var packages = []string{
"archive",
"archive/tar",
"archive/zip",
"bufio",
"builtin",
"bytes",
"compress",
"compress/bzip2",
"compress/flate",
"compress/gzip",
"compress/lzw",
"compress/zlib",
"container",
"container/heap",
"container/list",
"container/ring",
"crypto",
"crypto/aes",
"crypto/cipher",
"crypto/des",
"crypto/dsa",
"crypto/ecdsa",
"crypto/elliptic",
"crypto/hmac",
"crypto/md5",
"crypto/rand",
"crypto/rc4",
"crypto/rsa",
"crypto/sha1",
"crypto/sha256",
"crypto/sha512",
"crypto/subtle",
"crypto/tls",
"crypto/x509",
"crypto/x509/pkix",
"database",
"database/sql",
"database/sql/driver",
"debug",
"debug/dwarf",
"debug/elf",
"debug/gosym",
"debug/macho",
"debug/pe",
"encoding",
"encoding/ascii85",
"encoding/asn1",
"encoding/base32",
"encoding/base64",
"encoding/binary",
"encoding/csv",
"encoding/gob",
"encoding/hex",
"encoding/json",
"encoding/pem",
"encoding/xml",
"errors",
"expvar",
"flag",
"fmt",
"go",
"go/ast",
"go/build",
"go/doc",
"go/format",
"go/parser",
"go/printer",
"go/scanner",
"go/token",
"hash",
"hash/adler32",
"hash/crc32",
"hash/crc64",
"hash/fnv",
"html",
"html/template",
"image",
"image/color",
"image/draw",
"image/gif",
"image/jpeg",
"image/png",
"index",
"index/suffixarray",
"io",
"io/ioutil",
"log",
"log/syslog",
"math",
"math/big",
"math/cmplx",
"math/rand",
"mime",
"mime/multipart",
"net",
"net/http",
"net/http/cgi",
"net/http/cookiejar",
"net/http/fcgi",
"net/http/httptest",
"net/http/httputil",
"net/http/pprof",
"net/mail",
"net/rpc",
"net/rpc/jsonrpc",
"net/smtp",
"net/textproto",
"net/url",
"os",
"os/exec",
"os/signal",
"os/user",
"path",
"path/filepath",
"reflect",
"regexp",
"regexp/syntax",
"runtime",
"runtime/cgo",
"runtime/debug",
"runtime/pprof",
"runtime/race",
"sort",
"strconv",
"strings",
"sync",
"sync/atomic",
"syscall",
"testing",
"testing/iotest",
"testing/quick",
"text",
"text/scanner",
"text/tabwriter",
"text/template",
"text/template/parse",
"time",
"unicode",
"unicode/utf16",
"unicode/utf8",
"unsafe",
}
// Copyright 2013 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.
// The runstress tool stresses the runtime.
//
// It runs forever and should never fail. It tries to stress the garbage collector,
// maps, channels, the network, and everything else provided by the runtime.
package main
import (
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"math/rand"
"net"
"net/http"
"net/http/httptest"
"os/exec"
"strconv"
"time"
)
var (
v = flag.Bool("v", false, "verbose")
doMaps = flag.Bool("maps", true, "stress maps")
doExec = flag.Bool("exec", true, "stress exec")
doChan = flag.Bool("chan", true, "stress channels")
doNet = flag.Bool("net", true, "stress networking")
doParseGo = flag.Bool("parsego", true, "stress parsing Go (generates garbage)")
)
func Println(a ...interface{}) {
if *v {
log.Println(a...)
}
}
func dialStress(a net.Addr) {
for {
d := net.Dialer{Timeout: time.Duration(rand.Intn(1e9))}
c, err := d.Dial("tcp", a.String())
if err == nil {
Println("did dial")
go func() {
time.Sleep(time.Duration(rand.Intn(500)) * time.Millisecond)
c.Close()
Println("closed dial")
}()
}
// Don't run out of ephermeral ports too quickly:
time.Sleep(250 * time.Millisecond)
}
}
func stressNet() {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
size, _ := strconv.Atoi(r.FormValue("size"))
w.Write(make([]byte, size))
}))
go dialStress(ts.Listener.Addr())
for {
size := rand.Intn(128 << 10)
res, err := http.Get(fmt.Sprintf("%s/?size=%d", ts.URL, size))
if err != nil {
log.Fatalf("stressNet: http Get error: %v", err)
}
if res.StatusCode != 200 {
log.Fatalf("stressNet: Status code = %d", res.StatusCode)
}
n, err := io.Copy(ioutil.Discard, res.Body)
if err != nil {
log.Fatalf("stressNet: io.Copy: %v", err)
}
if n != int64(size) {
log.Fatalf("stressNet: copied = %d; want %d", n, size)
}
res.Body.Close()
Println("did http", size)
}
}
func doAnExec() {
exit := rand.Intn(2)
wantOutput := fmt.Sprintf("output-%d", rand.Intn(1e9))
cmd := exec.Command("/bin/sh", "-c", fmt.Sprintf("echo %s; exit %d", wantOutput, exit))
out, err := cmd.CombinedOutput()
if exit == 1 {
if err == nil {
log.Fatal("stressExec: unexpected exec success")
}
return
}
if err != nil {
log.Fatalf("stressExec: exec failure: %v: %s", err, out)
}
wantOutput += "\n"
if string(out) != wantOutput {
log.Fatalf("stressExec: exec output = %q; want %q", out, wantOutput)
}
Println("did exec")
}
func stressExec() {
gate := make(chan bool, 10) // max execs at once
for {
gate <- true
go func() {
doAnExec()
<-gate
}()
}
}
func ringf(in <-chan int, out chan<- int, donec chan<- bool) {
for {
n := <-in
if n == 0 {
donec <- true
return
}
out <- n - 1
}
}
func threadRing(bufsize int) {
const N = 100
donec := make(chan bool)
one := make(chan int, bufsize) // will be input to thread 1
var in, out chan int = nil, one
for i := 1; i <= N-1; i++ {
in, out = out, make(chan int, bufsize)
go ringf(in, out, donec)
}
go ringf(out, one, donec)
one <- N
<-donec
Println("did threadring of", bufsize)
}
func stressChannels() {
for {
threadRing(0)
threadRing(1)
}
}
func main() {
flag.Parse()
for want, f := range map[*bool]func(){
doMaps: stressMaps,
doNet: stressNet,
doExec: stressExec,
doChan: stressChannels,
doParseGo: stressParseGo,
} {
if *want {
go f()
}
}
select {}
}
...@@ -33,6 +33,7 @@ func assert(a, b, c string) { ...@@ -33,6 +33,7 @@ func assert(a, b, c string) {
print("\ta[", i, "] = ", ac, "; b[", i, "] =", bc, "\n") print("\ta[", i, "] = ", ac, "; b[", i, "] =", bc, "\n")
} }
} }
panic("string_lit")
} }
} }
...@@ -110,7 +111,7 @@ func main() { ...@@ -110,7 +111,7 @@ func main() {
r = -1 r = -1
s = string(r) s = string(r)
assert(s, "\xef\xbf\xbd", "negative rune") assert(s, "\xef\xbf\xbd", "negative rune")
// the large rune tests again, this time using constants instead of a variable. // the large rune tests again, this time using constants instead of a variable.
// these conversions will be done at compile time. // these conversions will be done at compile time.
s = string(0x10ffff) // largest rune value s = string(0x10ffff) // largest rune value
......
...@@ -305,11 +305,40 @@ func main() { ...@@ -305,11 +305,40 @@ func main() {
assert(false, "i should be true") assert(false, "i should be true")
} }
// switch on interface with constant cases differing by type.
// was rejected by compiler: see issue 4781
type T int
type B bool
type F float64
type S string
switch i := interface{}(float64(1.0)); i {
case nil:
assert(false, "i should be float64(1.0)")
case (*int)(nil):
assert(false, "i should be float64(1.0)")
case 1:
assert(false, "i should be float64(1.0)")
case T(1):
assert(false, "i should be float64(1.0)")
case F(1.0):
assert(false, "i should be float64(1.0)")
case 1.0:
assert(true, "true")
case "hello":
assert(false, "i should be float64(1.0)")
case S("hello"):
assert(false, "i should be float64(1.0)")
case true, B(false):
assert(false, "i should be float64(1.0)")
case false, B(true):
assert(false, "i should be float64(1.0)")
}
// switch on array. // switch on array.
switch ar := [3]int{1, 2, 3}; ar { switch ar := [3]int{1, 2, 3}; ar {
case [3]int{1,2,3}: case [3]int{1, 2, 3}:
assert(true, "[1 2 3]") assert(true, "[1 2 3]")
case [3]int{4,5,6}: case [3]int{4, 5, 6}:
assert(false, "ar should be [1 2 3]") assert(false, "ar should be [1 2 3]")
default: default:
assert(false, "ar should be [1 2 3]") assert(false, "ar should be [1 2 3]")
...@@ -327,12 +356,48 @@ func main() { ...@@ -327,12 +356,48 @@ func main() {
assert(false, "c1 did not match itself") assert(false, "c1 did not match itself")
} }
// empty switch
switch {
}
// empty switch with default case.
fired = false
switch {
default:
fired = true
}
assert(fired, "fail")
// Default and fallthrough.
count = 0
switch {
default:
count++
fallthrough
case false:
count++
}
assert(count == 2, "fail")
// fallthrough to default, which is not at end.
count = 0
switch i5 {
case 5:
count++
fallthrough
default:
count++
case 6:
count++
}
assert(count == 2, "fail")
i := 0 i := 0
switch x := 5; { switch x := 5; {
case i < x: case i < x:
os.Exit(0) os.Exit(0)
case i == x: case i == x:
case i > x: case i > x:
os.Exit(1) os.Exit(1)
} }
} }
// errorcheck
// Copyright 2011 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.
// Verify that erroneous switch statements are detected by the compiler.
// Does not compile.
package main
type I interface {
M()
}
func bad() {
i5 := 5
switch i5 {
case 5:
fallthrough // ERROR "cannot fallthrough final case in switch"
}
}
func good() {
var i interface{}
var s string
switch i {
case s:
}
switch s {
case i:
}
}
...@@ -5,23 +5,101 @@ ...@@ -5,23 +5,101 @@
# These function names are also known to # These function names are also known to
# (and are the plan for transitioning to) run.go. # (and are the plan for transitioning to) run.go.
# helper (not known to run.go)
# group file list by packages and return list of packages
# each package is a comma-separated list of go files.
pkgs() {
pkglist=$(grep -h '^package ' $* | awk '{print $2}' | sort -u)
for p in $pkglist
do
echo $(grep -l "^package $p\$" $*) | tr ' ' ,
done | sort
}
# +build aborts execution if the supplied tags don't match,
# i.e. none of the tags (x or !x) matches GOARCH or GOOS.
+build() {
if (( $# == 0 )); then
return
fi
for tag; do
case $tag in
$GOARCH|$GOOS)
#echo >&2 "match $tag in $1"
return # don't exclude.
;;
'!'$GOARCH|'!'$GOOS)
;;
'!'*)
# not x where x is neither GOOS nor GOARCH.
#echo >&2 "match $tag in $1"
return # don't exclude
;;
esac
done
# no match.
exit 0
}
compile() { compile() {
$G $D/$F.go $G $D/$F.go
} }
compiledir() { compiledir() {
for gofile in $D/$F.dir/*.go for pkg in $(pkgs $D/$F.dir/*.go)
do
$G -I . $(echo $pkg | tr , ' ') || return 1
done
}
errorcheckdir() {
lastzero=""
if [ "$1" = "-0" ]; then
lastzero="-0"
fi
pkgs=$(pkgs $D/$F.dir/*.go)
for pkg in $pkgs.last
do do
$G -I. "$gofile" || return 1 zero="-0"
case $pkg in
*.last)
pkg=$(echo $pkg |sed 's/\.last$//')
zero=$lastzero
esac
errchk $zero $G -D . -I . -e $(echo $pkg | tr , ' ')
done done
} }
rundir() {
lastfile=""
for pkg in $(pkgs $D/$F.dir/*.go)
do
name=$(echo $pkg | sed 's/\.go.*//; s/.*\///')
$G -D . -I . -e $(echo $pkg | tr , ' ') || return 1
lastfile=$name
done
$L -o $A.out -L . $lastfile.$A
./$A.out
}
rundircmpout() {
lastfile=""
for pkg in $(pkgs $D/$F.dir/*.go)
do
name=$(echo $pkg | sed 's/\.go.*//; s/.*\///')
$G -D . -I . -e $(echo $pkg | tr , ' ') || return 1
lastfile=$name
done
$L -o $A.out -L . $lastfile.$A
./$A.out 2>&1 | cmp - $D/$F.out
}
build() { build() {
$G $D/$F.go && $L $F.$A $G $D/$F.go && $L $F.$A
} }
runoutput() { runoutput() {
go run "$D/$F.go" > tmp.go go run "$D/$F.go" "$@" > tmp.go
go run tmp.go go run tmp.go
} }
...@@ -56,6 +134,16 @@ errorcheck() { ...@@ -56,6 +134,16 @@ errorcheck() {
errchk $zero $G -e $* $D/$F.go errchk $zero $G -e $* $D/$F.go
} }
errorcheckoutput() {
zero=""
if [ "$1" = "-0" ]; then
zero="-0"
shift
fi
go run "$D/$F.go" "$@" > tmp.go
errchk $zero $G -e tmp.go
}
skip() { skip() {
true true
} }
// compile
// Copyright 2012 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.
// Various tests for expressions with high complexity.
package main
// Concatenate 16 4-bit integers into a 64-bit number.
func concat(s *[16]byte) uint64 {
r := (((((((((((((((uint64(s[0])<<4|
uint64(s[1]))<<4|
uint64(s[2]))<<4|
uint64(s[3]))<<4|
uint64(s[4]))<<4|
uint64(s[5]))<<4|
uint64(s[6]))<<4|
uint64(s[7]))<<4|
uint64(s[8]))<<4|
uint64(s[9]))<<4|
uint64(s[10]))<<4|
uint64(s[11]))<<4|
uint64(s[12]))<<4|
uint64(s[13]))<<4|
uint64(s[14]))<<4 |
uint64(s[15]))
return r
}
// Compute the determinant of a 4x4-matrix by the sum
// over all index permutations.
func determinant(m [4][4]float64) float64 {
return m[0][0]*m[1][1]*m[2][2]*m[3][3] -
m[0][0]*m[1][1]*m[2][3]*m[3][2] -
m[0][0]*m[1][2]*m[2][1]*m[3][3] +
m[0][0]*m[1][2]*m[2][3]*m[3][1] +
m[0][0]*m[1][3]*m[2][1]*m[3][2] -
m[0][0]*m[1][3]*m[2][2]*m[3][1] -
m[0][1]*m[1][0]*m[2][2]*m[3][3] +
m[0][1]*m[1][0]*m[2][3]*m[3][2] +
m[0][1]*m[1][2]*m[2][0]*m[3][3] -
m[0][1]*m[1][2]*m[2][3]*m[3][0] -
m[0][1]*m[1][3]*m[2][0]*m[3][2] +
m[0][1]*m[1][3]*m[2][2]*m[3][0] +
m[0][2]*m[1][0]*m[2][1]*m[3][3] -
m[0][2]*m[1][0]*m[2][3]*m[3][1] -
m[0][2]*m[1][1]*m[2][0]*m[3][3] +
m[0][2]*m[1][1]*m[2][3]*m[3][0] +
m[0][2]*m[1][3]*m[2][0]*m[3][1] -
m[0][2]*m[1][3]*m[2][1]*m[3][0] -
m[0][3]*m[1][0]*m[2][1]*m[3][2] +
m[0][3]*m[1][0]*m[2][2]*m[3][1] +
m[0][3]*m[1][1]*m[2][0]*m[3][2] -
m[0][3]*m[1][1]*m[2][2]*m[3][0] -
m[0][3]*m[1][2]*m[2][0]*m[3][1] +
m[0][3]*m[1][2]*m[2][1]*m[3][0]
}
// Compute the determinant of a 4x4-matrix by the sum
// over all index permutations.
func determinantInt(m [4][4]int) int {
return m[0][0]*m[1][1]*m[2][2]*m[3][3] -
m[0][0]*m[1][1]*m[2][3]*m[3][2] -
m[0][0]*m[1][2]*m[2][1]*m[3][3] +
m[0][0]*m[1][2]*m[2][3]*m[3][1] +
m[0][0]*m[1][3]*m[2][1]*m[3][2] -
m[0][0]*m[1][3]*m[2][2]*m[3][1] -
m[0][1]*m[1][0]*m[2][2]*m[3][3] +
m[0][1]*m[1][0]*m[2][3]*m[3][2] +
m[0][1]*m[1][2]*m[2][0]*m[3][3] -
m[0][1]*m[1][2]*m[2][3]*m[3][0] -
m[0][1]*m[1][3]*m[2][0]*m[3][2] +
m[0][1]*m[1][3]*m[2][2]*m[3][0] +
m[0][2]*m[1][0]*m[2][1]*m[3][3] -
m[0][2]*m[1][0]*m[2][3]*m[3][1] -
m[0][2]*m[1][1]*m[2][0]*m[3][3] +
m[0][2]*m[1][1]*m[2][3]*m[3][0] +
m[0][2]*m[1][3]*m[2][0]*m[3][1] -
m[0][2]*m[1][3]*m[2][1]*m[3][0] -
m[0][3]*m[1][0]*m[2][1]*m[3][2] +
m[0][3]*m[1][0]*m[2][2]*m[3][1] +
m[0][3]*m[1][1]*m[2][0]*m[3][2] -
m[0][3]*m[1][1]*m[2][2]*m[3][0] -
m[0][3]*m[1][2]*m[2][0]*m[3][1] +
m[0][3]*m[1][2]*m[2][1]*m[3][0]
}
// Compute the determinant of a 4x4-matrix by the sum
// over all index permutations.
func determinantByte(m [4][4]byte) byte {
return m[0][0]*m[1][1]*m[2][2]*m[3][3] -
m[0][0]*m[1][1]*m[2][3]*m[3][2] -
m[0][0]*m[1][2]*m[2][1]*m[3][3] +
m[0][0]*m[1][2]*m[2][3]*m[3][1] +
m[0][0]*m[1][3]*m[2][1]*m[3][2] -
m[0][0]*m[1][3]*m[2][2]*m[3][1] -
m[0][1]*m[1][0]*m[2][2]*m[3][3] +
m[0][1]*m[1][0]*m[2][3]*m[3][2] +
m[0][1]*m[1][2]*m[2][0]*m[3][3] -
m[0][1]*m[1][2]*m[2][3]*m[3][0] -
m[0][1]*m[1][3]*m[2][0]*m[3][2] +
m[0][1]*m[1][3]*m[2][2]*m[3][0] +
m[0][2]*m[1][0]*m[2][1]*m[3][3] -
m[0][2]*m[1][0]*m[2][3]*m[3][1] -
m[0][2]*m[1][1]*m[2][0]*m[3][3] +
m[0][2]*m[1][1]*m[2][3]*m[3][0] +
m[0][2]*m[1][3]*m[2][0]*m[3][1] -
m[0][2]*m[1][3]*m[2][1]*m[3][0] -
m[0][3]*m[1][0]*m[2][1]*m[3][2] +
m[0][3]*m[1][0]*m[2][2]*m[3][1] +
m[0][3]*m[1][1]*m[2][0]*m[3][2] -
m[0][3]*m[1][1]*m[2][2]*m[3][0] -
m[0][3]*m[1][2]*m[2][0]*m[3][1] +
m[0][3]*m[1][2]*m[2][1]*m[3][0]
}
type A []A
// A sequence of constant indexings.
func IndexChain1(s A) A {
return s[0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0]
}
// A sequence of non-constant indexings.
func IndexChain2(s A, i int) A {
return s[i][i][i][i][i][i][i][i][i][i][i][i][i][i][i][i]
}
// Another sequence of indexings.
func IndexChain3(s []int) int {
return s[s[s[s[s[s[s[s[s[s[s[s[s[s[s[s[s[s[s[s[s[0]]]]]]]]]]]]]]]]]]]]]
}
// A right-leaning tree of byte multiplications.
func righttree(a, b, c, d uint8) uint8 {
return a * (b * (c * (d *
(a * (b * (c * (d *
(a * (b * (c * (d *
(a * (b * (c * (d *
(a * (b * (c * (d *
a * (b * (c * d)))))))))))))))))))))
}
// A left-leaning tree of byte multiplications.
func lefttree(a, b, c, d uint8) uint8 {
return ((((((((((((((((((a * b) * c) * d *
a) * b) * c) * d *
a) * b) * c) * d *
a) * b) * c) * d *
a) * b) * c) * d *
a) * b) * c) * d)
}
type T struct {
Next I
}
type I interface{}
// A chains of type assertions.
func ChainT(t *T) *T {
return t.
Next.(*T).
Next.(*T).
Next.(*T).
Next.(*T).
Next.(*T).
Next.(*T).
Next.(*T).
Next.(*T).
Next.(*T).
Next.(*T).
Next.(*T).
Next.(*T).
Next.(*T).
Next.(*T).
Next.(*T).
Next.(*T).
Next.(*T).
Next.(*T).
Next.(*T).
Next.(*T)
}
type U struct {
Children []J
}
func (u *U) Child(n int) J { return u.Children[n] }
type J interface {
Child(n int) J
}
func ChainUAssert(u *U) *U {
return u.Child(0).(*U).
Child(0).(*U).
Child(0).(*U).
Child(0).(*U).
Child(0).(*U).
Child(0).(*U).
Child(0).(*U).
Child(0).(*U).
Child(0).(*U).
Child(0).(*U).
Child(0).(*U).
Child(0).(*U).
Child(0).(*U).
Child(0).(*U).
Child(0).(*U).
Child(0).(*U).
Child(0).(*U).
Child(0).(*U).
Child(0).(*U).
Child(0).(*U).
Child(0).(*U).
Child(0).(*U)
}
func ChainUNoAssert(u *U) *U {
return u.Child(0).
Child(0).
Child(0).
Child(0).
Child(0).
Child(0).
Child(0).
Child(0).
Child(0).
Child(0).
Child(0).
Child(0).
Child(0).
Child(0).
Child(0).
Child(0).
Child(0).
Child(0).
Child(0).
Child(0).
Child(0).
Child(0).(*U)
}
// Type assertions and slice indexing. See issue 4207.
func ChainAssertIndex(u *U) J {
return u.
Children[0].(*U).
Children[0].(*U).
Children[0].(*U).
Children[0].(*U).
Children[0].(*U).
Children[0].(*U).
Children[0].(*U).
Children[0].(*U).
Children[0].(*U).
Children[0].(*U).
Children[0].(*U).
Children[0].(*U).
Children[0].(*U).
Children[0]
}
type UArr struct {
Children [2]J
}
func (u *UArr) Child(n int) J { return u.Children[n] }
func ChainAssertArrayIndex(u *UArr) J {
return u.
Children[0].(*UArr).
Children[0].(*UArr).
Children[0].(*UArr).
Children[0].(*UArr).
Children[0].(*UArr).
Children[0].(*UArr).
Children[0].(*UArr).
Children[0].(*UArr).
Children[0].(*UArr).
Children[0].(*UArr).
Children[0].(*UArr).
Children[0].(*UArr).
Children[0].(*UArr).
Children[0]
}
type UArrPtr struct {
Children *[2]J
}
func (u *UArrPtr) Child(n int) J { return u.Children[n] }
func ChainAssertArrayptrIndex(u *UArrPtr) J {
return u.
Children[0].(*UArrPtr).
Children[0].(*UArrPtr).
Children[0].(*UArrPtr).
Children[0].(*UArrPtr).
Children[0].(*UArrPtr).
Children[0].(*UArrPtr).
Children[0].(*UArrPtr).
Children[0].(*UArrPtr).
Children[0].(*UArrPtr).
Children[0].(*UArrPtr).
Children[0].(*UArrPtr).
Children[0].(*UArrPtr).
Children[0].(*UArrPtr).
Children[0]
}
// Chains of divisions. See issue 4201.
func ChainDiv(a, b int) int {
return a / b / a / b / a / b / a / b /
a / b / a / b / a / b / a / b /
a / b / a / b / a / b / a / b
}
func ChainDivRight(a, b int) int {
return a / (b / (a / (b /
(a / (b / (a / (b /
(a / (b / (a / (b /
(a / (b / (a / (b /
(a / (b / (a / b))))))))))))))))))
}
func ChainDivConst(a int) int {
return a / 17 / 17 / 17 /
17 / 17 / 17 / 17 /
17 / 17 / 17 / 17
}
func ChainMulBytes(a, b, c byte) byte {
return a*(a*(a*(a*(a*(a*(a*(a*(a*b+c)+c)+c)+c)+c)+c)+c)+c) + c
}
// errorcheck
// Verify that the Go compiler will not
// die after running into an undefined
// type in the argument list for a
// function.
// Does not compile.
package main
func mine(int b) int { // ERROR "undefined.*b"
return b + 2 // ERROR "undefined.*b"
}
func main() {
mine() // GCCGO_ERROR "not enough arguments"
c = mine() // ERROR "undefined.*c|not enough arguments" "cannot assign to c"
}
...@@ -237,4 +237,7 @@ func main() { ...@@ -237,4 +237,7 @@ func main() {
fmt.Printf("%v/%v: expected %g error; got %g\n", t.f, t.g, t.out, x) fmt.Printf("%v/%v: expected %g error; got %g\n", t.f, t.g, t.out, x)
} }
} }
if bad {
panic("zerodivide")
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment