Commit efcf639f by Ian Lance Taylor Committed by Ian Lance Taylor

Update to current Go testsuite.

	* go.test/go-test.exp (filecmp): New procedure.
	(errchk): Handle quoted square brackets.
	(go-gc-tests): Set go_compile_args. Handle various new test
	lines.  Skip a few new tests.
	* lib/go-torture.exp (go-torture-execute): Use go_compile_args.

From-SVN: r183502
parent d1cab3a6
2012-01-24 Ian Lance Taylor <iant@google.com>
* go.test/go-test.exp (filecmp): New procedure.
(errchk): Handle quoted square brackets.
(go-gc-tests): Set go_compile_args. Handle various new test
lines. Skip a few new tests.
* lib/go-torture.exp (go-torture-execute): Use go_compile_args.
2012-01-24 Richard Sandiford <rdsandiford@googlemail.com> 2012-01-24 Richard Sandiford <rdsandiford@googlemail.com>
* lib/target-supports.exp (proc check_effective_target_vect_perm) * lib/target-supports.exp (proc check_effective_target_vect_perm)
......
...@@ -34,6 +34,38 @@ ...@@ -34,6 +34,38 @@
load_lib go-dg.exp load_lib go-dg.exp
load_lib go-torture.exp load_lib go-torture.exp
# Compare two files
proc filecmp { file1 file2 testname } {
set f1 [open $file1 r]
set f2 [open $file2 r]
set ok 1
while { [gets $f1 line1] >= 0 } {
if { [gets $f2 line2] < 0 } {
verbose -log "output mismatch: $file2 shorter than $file1"
set ok 0
break
}
if { $line1 != $line2 } {
verbose -log "output mismatch comparing $file1 and $file2"
verbose -log "expected \"$line1\""
verbose -log "got \"$line2\""
set ok 0
break
}
}
if { [gets $f2 line2] >= 0 } {
verbose -log "output mismatch: $file1 shorter than $file2"
set ok 0
}
close $f1
close $f2
if { ! $ok } {
fail $testname
} else {
pass $testname
}
}
# Implement errchk # Implement errchk
proc errchk { test opts } { proc errchk { test opts } {
global dg-do-what-default global dg-do-what-default
...@@ -56,6 +88,14 @@ proc errchk { test opts } { ...@@ -56,6 +88,14 @@ proc errchk { test opts } {
continue continue
} }
regsub "// \(GCCGO_\)?ERROR \"\(\[^\"\]*\)\".*$" $copy_line "// \{ dg-error \"\\2\" \}" out_line regsub "// \(GCCGO_\)?ERROR \"\(\[^\"\]*\)\".*$" $copy_line "// \{ dg-error \"\\2\" \}" out_line
if [string match "*dg-error*\\\[*" $out_line] {
set index [string first "dg-error" $out_line]
regsub -start $index -all "\\\\\\\[" $out_line "\\\\\\\\\\\[" out_line
}
if [string match "*dg-error*\\\]*" $out_line] {
set index [string first "dg-error" $out_line]
regsub -start $index -all "\\\\\\\]" $out_line "\\\\\\\\\\\]" out_line
}
if [string match "*dg-error*.\**" $out_line] { if [string match "*dg-error*.\**" $out_line] {
# I worked out the right number of backslashes by # I worked out the right number of backslashes by
# experimentation, not analysis. # experimentation, not analysis.
...@@ -199,6 +239,7 @@ proc go-gc-tests { } { ...@@ -199,6 +239,7 @@ proc go-gc-tests { } {
global TOOL_OPTIONS global TOOL_OPTIONS
global TORTURE_OPTIONS global TORTURE_OPTIONS
global dg-do-what-default global dg-do-what-default
global go_compile_args
global go_execute_args global go_execute_args
global target_triplet global target_triplet
...@@ -230,13 +271,10 @@ proc go-gc-tests { } { ...@@ -230,13 +271,10 @@ proc go-gc-tests { } {
continue continue
} }
# Skip the files in bench and garbage; they are not tests. # Skip the files in bench; they are not tests.
if [string match "*go.test/test/bench/*" $test] { if [string match "*go.test/test/bench/*" $test] {
continue continue
} }
if [string match "*go.test/test/garbage/*" $test] {
continue
}
# Skip files in sub-subdirectories: they are components of # Skip files in sub-subdirectories: they are components of
# other tests. # other tests.
...@@ -274,6 +312,20 @@ proc go-gc-tests { } { ...@@ -274,6 +312,20 @@ proc go-gc-tests { } {
continue continue
} }
if { [file tail $test] == "init1.go" } {
# This tests whether GC runs during init, which for gccgo
# it currently does not.
untested $name
continue
}
if { [file tail $test] == "closure.go" } {
# This tests whether function closures do any memory
# allocation, which for gccgo they currently do.
untested $name
continue
}
set fd [open $test r] set fd [open $test r]
set lines_ok 1 set lines_ok 1
...@@ -290,7 +342,8 @@ proc go-gc-tests { } { ...@@ -290,7 +342,8 @@ proc go-gc-tests { } {
if { [ string match "*nacl*exit 0*" $test_line ] \ if { [ string match "*nacl*exit 0*" $test_line ] \
|| [ string match "*exit 0*nacl*" $test_line ] \ || [ string match "*exit 0*nacl*" $test_line ] \
|| [ string match "*Android*exit 0*" $test_line ] \ || [ string match "*Android*exit 0*" $test_line ] \
|| [ string match "*exit 0*Android*" $test_line ] } { || [ string match "*exit 0*Android*" $test_line ] \
|| [ string match "*\"\$GOOS\" == windows*" $test_line ] } {
continue continue
} }
...@@ -320,8 +373,9 @@ proc go-gc-tests { } { ...@@ -320,8 +373,9 @@ proc go-gc-tests { } {
close $fd close $fd
set go_compile_args ""
set go_execute_args "" set go_execute_args ""
if { [regexp ".*\\\$A.out (\[^|&>\].*)\$" $test_line match progargs] } { if { [regexp ".*\\\$A.out (\[^|&>2\].*)\$" $test_line match 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]
...@@ -393,6 +447,33 @@ proc go-gc-tests { } { ...@@ -393,6 +447,33 @@ proc go-gc-tests { } {
# This is a vanilla execution test. # This is a vanilla execution test.
go-torture-execute $test go-torture-execute $test
file delete core [glob -nocomplain core.*] file delete core [glob -nocomplain core.*]
} elseif { $test_line == "// \$G \$D/\$F.go && \$L \$F.\$A && ./\$A.out 2>&1 | cmp - \$D/\$F.out" \
|| $test_line == "// (\$G \$D/\$F.go && \$L \$F.\$A && ./\$A.out 2>&1 | cmp - \$D/\$F.out)" } {
# This is an execution test for which we need to check the
# program output.
set hold_runtests $runtests
set runtests "go-test.exp"
set dg-do-what-default "link"
dg-test -keep-output $test "-O" "-w $DEFAULT_GOCFLAGS"
set output_file "./[file rootname [file tail $test]].exe"
set base "[file rootname [file tail $test]]"
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"
}
#file delete $base.p
} else {
untested "$name execution"
untested "$name compare"
}
set runtests $hold_runtests
} elseif { [string match \ } elseif { [string match \
"// \$G \$D/\$F.go && \$L \$F.\$A || echo BUG*" \ "// \$G \$D/\$F.go && \$L \$F.\$A || echo BUG*" \
$test_line] \ $test_line] \
...@@ -405,6 +486,10 @@ proc go-gc-tests { } { ...@@ -405,6 +486,10 @@ proc go-gc-tests { } {
} elseif { [string match "// \$G \$D/\$F.go" $test_line] \ } elseif { [string match "// \$G \$D/\$F.go" $test_line] \
|| [string match "// \$G \$D/\$F.go || echo BUG*" \ || [string match "// \$G \$D/\$F.go || echo BUG*" \
$test_line] \ $test_line] \
|| [string match "// \$G \$D/\$F.go || echo \"Bug*" \
$test_line] \
|| [string match "// \$G \$D/\$F.go || echo \"Issue*" \
$test_line] \
|| [string match "// \$G \$F.go || echo BUG*" \ || [string match "// \$G \$F.go || echo BUG*" \
$test_line] \ $test_line] \
|| [string match "// ! \$G \$D/\$F.go && echo BUG*" \ || [string match "// ! \$G \$D/\$F.go && echo BUG*" \
...@@ -452,13 +537,27 @@ proc go-gc-tests { } { ...@@ -452,13 +537,27 @@ proc go-gc-tests { } {
errchk $test "" errchk $test ""
} elseif { [string match \ } elseif { [string match \
"// \$G \$D/\$F.dir/bug0.go && \$G \$D/\$F.dir/bug1.go || echo BUG*" \ "// \$G \$D/\$F.dir/bug0.go && \$G \$D/\$F.dir/bug1.go || echo BUG*" \
$test_line] } { $test_line] \
|| [string match \
"// \$G \$D/\$F.dir/one.go && \$G \$D/\$F.dir/two.go" \
$test_line] } {
if { [string match \
"// \$G \$D/\$F.dir/bug0.go && \$G \$D/\$F.dir/bug1.go || echo BUG*" \
$test_line] } {
set name1 "bug0.go"
set name2 "bug1.go"
} elseif { [string match \
"// \$G \$D/\$F.dir/one.go && \$G \$D/\$F.dir/two.go" \
$test_line] } {
set name1 "one.go"
set name2 "two.go"
}
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 dg-do-what-default "assemble"
regsub "\\.go$" $test ".dir/bug0.go" file1 regsub "\\.go$" $test ".dir/$name1" file1
dg-test -keep-output $file1 "-O" "-w $DEFAULT_GOCFLAGS" dg-test -keep-output $file1 "-O" "-w $DEFAULT_GOCFLAGS"
regsub "\\.go$" $test ".dir/bug1.go" file2 regsub "\\.go$" $test ".dir/$name2" file2
dg-test $file2 "-O" "-w $DEFAULT_GOCFLAGS" dg-test $file2 "-O" "-w $DEFAULT_GOCFLAGS"
file delete "[file rootname [file tail $file1]].o" file delete "[file rootname [file tail $file1]].o"
set runtests $hold_runtests set runtests $hold_runtests
...@@ -650,14 +749,28 @@ proc go-gc-tests { } { ...@@ -650,14 +749,28 @@ proc go-gc-tests { } {
set runtests $hold_runtests set runtests $hold_runtests
} elseif { [string match \ } elseif { [string match \
"// \$G \$D/\$F.dir/lib.go && \$G \$D/\$F.dir/main.go && \$L main.\$A && ./\$A.out || echo BUG*" \ "// \$G \$D/\$F.dir/lib.go && \$G \$D/\$F.dir/main.go && \$L main.\$A && ./\$A.out || echo BUG*" \
$test_line ] } { $test_line ] || \
[string match \
"// \$G \$D/\$F.dir/p.go && \$G \$D/\$F.dir/main.go && \$L main.\$A && ./\$A.out || echo BUG*" \
$test_line ] } {
if { [string match \
"// \$G \$D/\$F.dir/lib.go && \$G \$D/\$F.dir/main.go && \$L main.\$A && ./\$A.out || echo BUG*" \
$test_line ] } {
set name1 "lib.go"
set name2 "main.go"
} elseif { [string match \
"// \$G \$D/\$F.dir/p.go && \$G \$D/\$F.dir/main.go && \$L main.\$A && ./\$A.out || echo BUG*" \
$test_line ] } {
set name1 "p.go"
set name2 "main.go"
}
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 dg-do-what-default "assemble"
regsub "\\.go$" $test ".dir/lib.go" file1 regsub "\\.go$" $test ".dir/$name1" file1
dg-test -keep-output $file1 "-O" "-w $DEFAULT_GOCFLAGS" dg-test -keep-output $file1 "-O" "-w $DEFAULT_GOCFLAGS"
set ofile1 "[file rootname [file tail $file1]].o" set ofile1 "[file rootname [file tail $file1]].o"
regsub "\\.go$" $test ".dir/main.go" file2 regsub "\\.go$" $test ".dir/$name2" file2
dg-test -keep-output $file2 "-O" "-w $DEFAULT_GOCFLAGS" dg-test -keep-output $file2 "-O" "-w $DEFAULT_GOCFLAGS"
set ofile2 "[file rootname [file tail $file2]].o" set ofile2 "[file rootname [file tail $file2]].o"
set dg-do-what-default "link" set dg-do-what-default "link"
...@@ -705,7 +818,7 @@ proc go-gc-tests { } { ...@@ -705,7 +818,7 @@ proc go-gc-tests { } {
errchk $file2 "" errchk $file2 ""
file delete "[file rootname [file tail $file1]].o" file delete "[file rootname [file tail $file1]].o"
set runtests $hold_runtests set runtests $hold_runtests
} elseif { [string match "// true*" $test_line] } { } elseif { "$test_line" == "" || [string match "// true*" $test_line] } {
# Not a real test, just ignore. # Not a real test, just ignore.
} elseif { $test_line == "// \$G \$D/\$F.dir/bug0.go &&" \ } elseif { $test_line == "// \$G \$D/\$F.dir/bug0.go &&" \
&& $test_line2 == "// \$G \$D/\$F.dir/bug1.go &&" \ && $test_line2 == "// \$G \$D/\$F.dir/bug1.go &&" \
...@@ -886,7 +999,7 @@ proc go-gc-tests { } { ...@@ -886,7 +999,7 @@ proc go-gc-tests { } {
file delete $base-out.x file delete $base-out.x
go-torture-execute "./$base-out.go" go-torture-execute "./$base-out.go"
} }
# file delete $base-out.go file delete $base-out.go
} }
file delete $output_file file delete $output_file
set runtests $hold_runtests set runtests $hold_runtests
...@@ -894,23 +1007,96 @@ proc go-gc-tests { } { ...@@ -894,23 +1007,96 @@ 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 &&" \
&& $test_line2 == "// \$G -o fast.\$A \$D/bug369.dir/pkg.go &&" \
&& $test_line3 == "// \$G \$D/\$F.go && \$L \$F.\$A && ./\$A.out" } {
set hold_runtests $runtests
set runtests "go-test.exp"
set dg-do-what-default "assemble"
regsub "\\.go$" $test ".dir/pkg.go" file1
dg-test -keep-output $file1 "" "-fgo-prefix=slow -w $DEFAULT_GOCFLAGS"
set ofile1 "[file rootname [file tail $file1]].o"
file rename -force $ofile1 slow.o
dg-test -keep-output $file1 "-O2" "-fgo-prefix=fast -w $DEFAULT_GOCFLAGS"
file rename -force $ofile1 fast.o
set ofile2 "[file rootname [file tail $test]].o"
dg-test -keep-output $test "-O" "-w $DEFAULT_GOCFLAGS"
set output_file "./[file rootname [file tail $test]].exe"
set comp_output [go_target_compile "$ofile2 slow.o fast.o" \
$output_file "executable" "$options"]
set comp_output [go-dg-prune $target_triplet $comp_output]
if [string match "" $comp_output] {
set result [go_load "$output_file" "" ""]
set status [lindex $result 0]
$status $name
} else {
verbose -log $comp_output
fail $name
}
file delete slow.o fast.o $ofile2 $output_file
set runtests $hold_runtests
} elseif { [string match \
"// \$G \$D/\$F.dir/pkg.go && \$G \$D/\$F.go || echo *" \
$test_line ] } {
set hold_runtests $runtests
set runtests "go-test.exp"
set dg-do-what-default "assemble"
regsub "\\.go$" $test ".dir/pkg.go" file1
dg-test -keep-output $file1 "-O" "-w $DEFAULT_GOCFLAGS"
dg-test $test "-O" "-w $DEFAULT_GOCFLAGS"
file delete "[file rootname [file tail $file1]].o"
set runtests $hold_runtests
} elseif { $test_line == "// \$G \$D/\$F.go && \$L \$F.\$A && ./\$A.out >tmp.go &&"
&& $test_line2 == "// \$G tmp.go && \$L tmp.\$A && ./\$A.out" } {
set go_execute_args ""
set hold_runtests $runtests
set runtests "go-test.exp"
set dg-do-what-default "link"
dg-test -keep-output $test "-O" "-w $DEFAULT_GOCFLAGS"
set output_file "./[file rootname [file tail $test]].exe"
set base "[file rootname [file tail $test]]"
if [isnative] {
if { [catch "exec $output_file >$base-out.go"] != 0 } {
fail "$name execution"
} else {
pass "$name execution"
file delete $base-out.x
go-torture-execute "./$base-out.go"
}
file delete $base-out.go
}
file delete $output_file
set runtests $hold_runtests
} elseif { $test_line == "// # generated by cmplxdivide.c" } { } elseif { $test_line == "// # generated by cmplxdivide.c" } {
# Ignore. # Ignore.
} elseif { $test_line == "// \$G \$D/bug302.dir/p.go && gopack grc pp.a p.\$A && \$G \$D/bug302.dir/main.go" \ } elseif { $test_line == "// \$G \$D/bug302.dir/p.go && gopack grc pp.a p.\$A && \$G \$D/bug302.dir/main.go" \
|| $test_line == "// \$G \$D/empty.go && errchk \$G \$D/\$F.go" } { || $test_line == "// \$G \$D/empty.go && errchk \$G \$D/\$F.go" } {
# These tests import the same package under two different # These tests import the same package under two different
# names, which gccgo does not support. # names, which gccgo does not support.
} elseif { $test_line == "// \$G -S \$D/\$F.go | egrep initdone >/dev/null && echo FAIL || true" } { } elseif { $test_line == "// \$G -S \$D/\$F.go | egrep initdone >/dev/null && echo BUG sinit || true" } {
# This tests whether initializers are written out # This tests whether initializers are written out
# statically. gccgo does not provide a way to test that, # statically. gccgo does not provide a way to test that,
# as an initializer will be generated for any code which # as an initializer will be generated for any code which
# has global variables which need to be registered as GC # has global variables which need to be registered as GC
# roots. # roots.
} elseif { $test_line == "// errchk -0 \$G -m -l \$D/\$F.go" } {
# This tests debug output of the gc compiler, which is
# meaningless for gccgo.
} elseif { $test_line == "// \[ \$O == 6 \] || errchk \$G -e \$D/\$F.go" \
|| $test_line == "// \[ \$O != 6 \] || errchk \$G -e \$D/\$F.go" } {
# This tests specific handling of the gc compiler on types
# that are too large. It is target specific in a way I
# haven't bothered to check for here.
} else { } else {
clone_output "$name: unrecognized test line: $test_line" clone_output "$name: unrecognized test line: $test_line"
unsupported $name unsupported $name
} }
set go_compile_args ""
set go_execute_args "" set go_execute_args ""
} }
......
// errchk $G -e $D/$F.go
// 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.
package main
// Test that error messages say what the source file says
// (uint8 vs byte, int32 vs. rune).
import (
"fmt"
"unicode/utf8"
)
func f(byte) {}
func g(uint8) {}
func main() {
var x float64
f(x) // ERROR "byte"
g(x) // ERROR "uint8"
// Test across imports.
var ff fmt.Formatter
var fs fmt.State
ff.Format(fs, x) // ERROR "rune"
utf8.RuneStart(x) // ERROR "byte"
}
// $G $D/$F.go && $L $F.$A && ./$A.out
// 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.
package main
// Test that dynamic interface checks treat byte=uint8
// and rune=int or rune=int32.
func main() {
var x interface{}
x = byte(1)
switch x.(type) {
case uint8:
// ok
default:
println("byte != uint8")
}
x = uint8(2)
switch x.(type) {
case byte:
// ok
default:
println("uint8 != byte")
}
rune32 := false
x = rune(3)
switch x.(type) {
case int:
// ok
case int32:
// must be new code
rune32 = true
default:
println("rune != int and rune != int32")
}
if rune32 {
x = int32(4)
} else {
x = int(5)
}
switch x.(type) {
case rune:
// ok
default:
println("int (or int32) != rune")
}
}
...@@ -63,6 +63,11 @@ var tests = []struct { ...@@ -63,6 +63,11 @@ var tests = []struct {
{"byte i", append([]byte{0, 1, 2}, []byte{3}...), []byte{0, 1, 2, 3}}, {"byte i", append([]byte{0, 1, 2}, []byte{3}...), []byte{0, 1, 2, 3}},
{"byte j", append([]byte{0, 1, 2}, []byte{3, 4, 5}...), []byte{0, 1, 2, 3, 4, 5}}, {"byte j", append([]byte{0, 1, 2}, []byte{3, 4, 5}...), []byte{0, 1, 2, 3, 4, 5}},
{"bytestr a", append([]byte{}, "0"...), []byte("0")},
{"bytestr b", append([]byte{}, "0123"...), []byte("0123")},
{"bytestr c", append([]byte("012"), "3"...), []byte("0123")},
{"bytestr d", append([]byte("012"), "345"...), []byte("012345")},
{"int16 a", append([]int16{}), []int16{}}, {"int16 a", append([]int16{}), []int16{}},
{"int16 b", append([]int16{}, 0), []int16{0}}, {"int16 b", append([]int16{}, 0), []int16{0}},
......
...@@ -2,23 +2,24 @@ ...@@ -2,23 +2,24 @@
# 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.
include ../../src/Make.inc include ../../../src/Make.inc
ALL=\ ALL=\
parser\ parser\
peano\ peano\
tree\ tree\
tree2\
all: $(addsuffix .out, $(ALL)) all: $(addsuffix .out, $(ALL))
%.$O: %.go stats.go %.$O: %.go stats.go
$(GC) $*.go stats.go $(GC) $(GCFLAGS) $(GCIMPORTS) $*.go stats.go
%.out: %.$O %.out: %.$O
$(LD) -o $@ $*.$O $(LD) -o $@ $*.$O
%.bench: %.out %.bench: %.out
./$*.out time ./$*.out
bench: $(addsuffix .bench, $(ALL)) bench: $(addsuffix .bench, $(ALL))
......
...@@ -12,27 +12,27 @@ import ( ...@@ -12,27 +12,27 @@ import (
"go/ast" "go/ast"
"go/parser" "go/parser"
"go/token" "go/token"
"log"
"net/http"
_ "net/http/pprof"
"os" "os"
"path" "path"
"runtime" "runtime"
"strings" "strings"
"time" "time"
"http"
_ "http/pprof"
"log"
) )
var serve = flag.String("serve", "", "serve http on this address at end") var serve = flag.String("serve", "", "serve http on this address at end")
func isGoFile(dir *os.FileInfo) bool { func isGoFile(dir os.FileInfo) bool {
return dir.IsRegular() && return !dir.IsDir() &&
!strings.HasPrefix(dir.Name, ".") && // ignore .files !strings.HasPrefix(dir.Name(), ".") && // ignore .files
path.Ext(dir.Name) == ".go" path.Ext(dir.Name()) == ".go"
} }
func isPkgFile(dir *os.FileInfo) bool { func isPkgFile(dir os.FileInfo) bool {
return isGoFile(dir) && return isGoFile(dir) &&
!strings.HasSuffix(dir.Name, "_test.go") // ignore test files !strings.HasSuffix(dir.Name(), "_test.go") // ignore test files
} }
func pkgName(filename string) string { func pkgName(filename string) string {
...@@ -49,7 +49,7 @@ func parseDir(dirpath string) map[string]*ast.Package { ...@@ -49,7 +49,7 @@ func parseDir(dirpath string) map[string]*ast.Package {
_, pkgname := path.Split(dirpath) _, pkgname := path.Split(dirpath)
// filter function to select the desired .go files // filter function to select the desired .go files
filter := func(d *os.FileInfo) bool { filter := func(d os.FileInfo) bool {
if isPkgFile(d) { if isPkgFile(d) {
// Some directories contain main packages: Only accept // Some directories contain main packages: Only accept
// files that belong to the expected package so that // files that belong to the expected package so that
...@@ -57,7 +57,7 @@ func parseDir(dirpath string) map[string]*ast.Package { ...@@ -57,7 +57,7 @@ func parseDir(dirpath string) map[string]*ast.Package {
// found" errors. // found" errors.
// Additionally, accept the special package name // Additionally, accept the special package name
// fakePkgName if we are looking at cmd documentation. // fakePkgName if we are looking at cmd documentation.
name := pkgName(dirpath + "/" + d.Name) name := pkgName(dirpath + "/" + d.Name())
return name == pkgname return name == pkgname
} }
return false return false
...@@ -66,17 +66,13 @@ func parseDir(dirpath string) map[string]*ast.Package { ...@@ -66,17 +66,13 @@ func parseDir(dirpath string) map[string]*ast.Package {
// get package AST // get package AST
pkgs, err := parser.ParseDir(token.NewFileSet(), dirpath, filter, parser.ParseComments) pkgs, err := parser.ParseDir(token.NewFileSet(), dirpath, filter, parser.ParseComments)
if err != nil { if err != nil {
println("parse", dirpath, err.String()) println("parse", dirpath, err.Error())
panic("fail") panic("fail")
} }
return pkgs return pkgs
} }
func main() { func main() {
runtime.GOMAXPROCS(4)
go func() {}()
go func() {}()
go func() {}()
st := &runtime.MemStats st := &runtime.MemStats
packages = append(packages, packages...) packages = append(packages, packages...)
packages = append(packages, packages...) packages = append(packages, packages...)
...@@ -86,7 +82,7 @@ func main() { ...@@ -86,7 +82,7 @@ func main() {
flag.Parse() flag.Parse()
var lastParsed []map[string]*ast.Package var lastParsed []map[string]*ast.Package
var t0 int64 var t0 time.Time
pkgroot := runtime.GOROOT() + "/src/pkg/" pkgroot := runtime.GOROOT() + "/src/pkg/"
for pass := 0; pass < 2; pass++ { for pass := 0; pass < 2; pass++ {
// Once the heap is grown to full size, reset counters. // Once the heap is grown to full size, reset counters.
...@@ -95,7 +91,7 @@ func main() { ...@@ -95,7 +91,7 @@ func main() {
// the average look much better than it actually is. // the average look much better than it actually is.
st.NumGC = 0 st.NumGC = 0
st.PauseTotalNs = 0 st.PauseTotalNs = 0
t0 = time.Nanoseconds() t0 = time.Now()
for i := 0; i < *n; i++ { for i := 0; i < *n; i++ {
parsed := make([]map[string]*ast.Package, *p) parsed := make([]map[string]*ast.Package, *p)
...@@ -109,7 +105,7 @@ func main() { ...@@ -109,7 +105,7 @@ func main() {
runtime.GC() runtime.GC()
runtime.GC() runtime.GC()
} }
t1 := time.Nanoseconds() t1 := time.Now()
fmt.Printf("Alloc=%d/%d Heap=%d Mallocs=%d PauseTime=%.3f/%d = %.3f\n", fmt.Printf("Alloc=%d/%d Heap=%d Mallocs=%d PauseTime=%.3f/%d = %.3f\n",
st.Alloc, st.TotalAlloc, st.Alloc, st.TotalAlloc,
...@@ -124,7 +120,7 @@ func main() { ...@@ -124,7 +120,7 @@ func main() {
} }
*/ */
// Standard gotest benchmark output, collected by build dashboard. // Standard gotest benchmark output, collected by build dashboard.
gcstats("BenchmarkParser", *n, t1-t0) gcstats("BenchmarkParser", *n, t1.Sub(t0))
if *serve != "" { if *serve != "" {
log.Fatal(http.ListenAndServe(*serve, nil)) log.Fatal(http.ListenAndServe(*serve, nil))
...@@ -132,23 +128,20 @@ func main() { ...@@ -132,23 +128,20 @@ func main() {
} }
} }
var packages = []string{ var packages = []string{
"archive/tar", "archive/tar",
"asn1", "encoding/asn1",
"big", "math/big",
"bufio", "bufio",
"bytes", "bytes",
"cmath", "math/cmplx",
"compress/flate", "compress/flate",
"compress/gzip", "compress/gzip",
"compress/zlib", "compress/zlib",
"container/heap", "container/heap",
"container/list", "container/list",
"container/ring", "container/ring",
"container/vector",
"crypto/aes", "crypto/aes",
"crypto/block",
"crypto/blowfish", "crypto/blowfish",
"crypto/hmac", "crypto/hmac",
"crypto/md4", "crypto/md4",
...@@ -167,20 +160,14 @@ var packages = []string{ ...@@ -167,20 +160,14 @@ var packages = []string{
"debug/macho", "debug/macho",
"debug/elf", "debug/elf",
"debug/gosym", "debug/gosym",
"debug/proc", "exp/ebnf",
"ebnf",
"encoding/ascii85", "encoding/ascii85",
"encoding/base64", "encoding/base64",
"encoding/binary", "encoding/binary",
"encoding/git85", "encoding/git85",
"encoding/hex", "encoding/hex",
"encoding/pem", "encoding/pem",
"exec", "os/exec",
"exp/datafmt",
"exp/draw",
"exp/eval",
"exp/iterable",
"expvar",
"flag", "flag",
"fmt", "fmt",
"go/ast", "go/ast",
...@@ -189,18 +176,18 @@ var packages = []string{ ...@@ -189,18 +176,18 @@ var packages = []string{
"go/printer", "go/printer",
"go/scanner", "go/scanner",
"go/token", "go/token",
"gob", "encoding/gob",
"hash", "hash",
"hash/adler32", "hash/adler32",
"hash/crc32", "hash/crc32",
"hash/crc64", "hash/crc64",
"http", "net/http",
"image", "image",
"image/jpeg", "image/jpeg",
"image/png", "image/png",
"io", "io",
"io/ioutil", "io/ioutil",
"json", "encoding/json",
"log", "log",
"math", "math",
"mime", "mime",
...@@ -209,29 +196,29 @@ var packages = []string{ ...@@ -209,29 +196,29 @@ var packages = []string{
"os/signal", "os/signal",
"patch", "patch",
"path", "path",
"rand", "math/rand",
"reflect", "reflect",
"regexp", "regexp",
"rpc", "net/rpc",
"runtime", "runtime",
"scanner", "text/scanner",
"sort", "sort",
"smtp", "net/smtp",
"strconv", "strconv",
"strings", "strings",
"sync", "sync",
"syscall", "syscall",
"syslog", "log/syslog",
"tabwriter", "text/tabwriter",
"template", "text/template",
"testing", "testing",
"testing/iotest", "testing/iotest",
"testing/quick", "testing/quick",
"testing/script", "testing/script",
"time", "time",
"unicode", "unicode",
"utf8", "unicode/utf8",
"utf16", "unicode/utf16",
"websocket", "websocket",
"xml", "encoding/xml",
} }
...@@ -12,31 +12,25 @@ import ( ...@@ -12,31 +12,25 @@ import (
"time" "time"
) )
type Number struct { type Number struct {
next *Number next *Number
} }
// ------------------------------------- // -------------------------------------
// Peano primitives // Peano primitives
func zero() *Number { return nil } func zero() *Number { return nil }
func is_zero(x *Number) bool { return x == nil } func is_zero(x *Number) bool { return x == nil }
func add1(x *Number) *Number { func add1(x *Number) *Number {
e := new(Number) e := new(Number)
e.next = x e.next = x
return e return e
} }
func sub1(x *Number) *Number { return x.next } func sub1(x *Number) *Number { return x.next }
func add(x, y *Number) *Number { func add(x, y *Number) *Number {
if is_zero(y) { if is_zero(y) {
return x return x
...@@ -45,7 +39,6 @@ func add(x, y *Number) *Number { ...@@ -45,7 +39,6 @@ func add(x, y *Number) *Number {
return add(add1(x), sub1(y)) return add(add1(x), sub1(y))
} }
func mul(x, y *Number) *Number { func mul(x, y *Number) *Number {
if is_zero(x) || is_zero(y) { if is_zero(x) || is_zero(y) {
return zero() return zero()
...@@ -54,7 +47,6 @@ func mul(x, y *Number) *Number { ...@@ -54,7 +47,6 @@ func mul(x, y *Number) *Number {
return add(mul(x, sub1(y)), x) return add(mul(x, sub1(y)), x)
} }
func fact(n *Number) *Number { func fact(n *Number) *Number {
if is_zero(n) { if is_zero(n) {
return add1(zero()) return add1(zero())
...@@ -63,7 +55,6 @@ func fact(n *Number) *Number { ...@@ -63,7 +55,6 @@ func fact(n *Number) *Number {
return mul(fact(sub1(n)), n) return mul(fact(sub1(n)), n)
} }
// ------------------------------------- // -------------------------------------
// Helpers to generate/count Peano integers // Helpers to generate/count Peano integers
...@@ -75,7 +66,6 @@ func gen(n int) *Number { ...@@ -75,7 +66,6 @@ func gen(n int) *Number {
return zero() return zero()
} }
func count(x *Number) int { func count(x *Number) int {
if is_zero(x) { if is_zero(x) {
return 0 return 0
...@@ -84,7 +74,6 @@ func count(x *Number) int { ...@@ -84,7 +74,6 @@ func count(x *Number) int {
return count(sub1(x)) + 1 return count(sub1(x)) + 1
} }
func check(x *Number, expected int) { func check(x *Number, expected int) {
var c = count(x) var c = count(x)
if c != expected { if c != expected {
...@@ -92,7 +81,6 @@ func check(x *Number, expected int) { ...@@ -92,7 +81,6 @@ func check(x *Number, expected int) {
} }
} }
// ------------------------------------- // -------------------------------------
// Test basic functionality // Test basic functionality
...@@ -117,19 +105,17 @@ func verify() { ...@@ -117,19 +105,17 @@ func verify() {
check(fact(gen(5)), 120) check(fact(gen(5)), 120)
} }
// ------------------------------------- // -------------------------------------
// Factorial // Factorial
func main() { func main() {
t0 := time.Nanoseconds() t0 := time.Now()
verify() verify()
for i := 0; i <= 9; i++ { for i := 0; i <= 9; i++ {
print(i, "! = ", count(fact(gen(i))), "\n") print(i, "! = ", count(fact(gen(i))), "\n")
} }
runtime.GC() runtime.GC()
t1 := time.Nanoseconds() t1 := time.Now()
gcstats("BenchmarkPeano", 1, t1-t0) gcstats("BenchmarkPeano", 1, t1.Sub(t0))
} }
...@@ -8,12 +8,13 @@ import ( ...@@ -8,12 +8,13 @@ import (
"fmt" "fmt"
"runtime" "runtime"
"sort" "sort"
"time"
) )
func gcstats(name string, n int, t int64) { func gcstats(name string, n int, t time.Duration) {
st := &runtime.MemStats st := &runtime.MemStats
fmt.Printf("garbage.%sMem Alloc=%d/%d Heap=%d NextGC=%d Mallocs=%d\n", name, st.Alloc, st.TotalAlloc, st.Sys, st.NextGC, st.Mallocs) fmt.Printf("garbage.%sMem Alloc=%d/%d Heap=%d NextGC=%d Mallocs=%d\n", name, st.Alloc, st.TotalAlloc, st.Sys, st.NextGC, st.Mallocs)
fmt.Printf("garbage.%s %d %d ns/op\n", name, n, t/int64(n)) fmt.Printf("garbage.%s %d %d ns/op\n", name, n, t.Nanoseconds()/int64(n))
fmt.Printf("garbage.%sLastPause 1 %d ns/op\n", name, st.PauseNs[(st.NumGC-1)%uint32(len(st.PauseNs))]) fmt.Printf("garbage.%sLastPause 1 %d ns/op\n", name, st.PauseNs[(st.NumGC-1)%uint32(len(st.PauseNs))])
fmt.Printf("garbage.%sPause %d %d ns/op\n", name, st.NumGC, int64(st.PauseTotalNs)/int64(st.NumGC)) fmt.Printf("garbage.%sPause %d %d ns/op\n", name, st.NumGC, int64(st.PauseTotalNs)/int64(st.NumGC))
nn := int(st.NumGC) nn := int(st.NumGC)
...@@ -22,13 +23,14 @@ func gcstats(name string, n int, t int64) { ...@@ -22,13 +23,14 @@ func gcstats(name string, n int, t int64) {
} }
t1, t2, t3, t4, t5 := tukey5(st.PauseNs[0:nn]) t1, t2, t3, t4, t5 := tukey5(st.PauseNs[0:nn])
fmt.Printf("garbage.%sPause5: %d %d %d %d %d\n", name, t1, t2, t3, t4, t5) fmt.Printf("garbage.%sPause5: %d %d %d %d %d\n", name, t1, t2, t3, t4, t5)
// fmt.Printf("garbage.%sScan: %v\n", name, st.ScanDist) // fmt.Printf("garbage.%sScan: %v\n", name, st.ScanDist)
} }
type T []uint64 type T []uint64
func (t T) Len() int { return len(t) }
func (t T) Swap(i, j int) { t[i], t[j] = t[j], t[i] } func (t T) Len() int { return len(t) }
func (t T) Swap(i, j int) { t[i], t[j] = t[j], t[i] }
func (t T) Less(i, j int) bool { return t[i] < t[j] } func (t T) Less(i, j int) bool { return t[i] < t[j] }
func tukey5(raw []uint64) (lo, q1, q2, q3, hi uint64) { func tukey5(raw []uint64) (lo, q1, q2, q3, hi uint64) {
......
...@@ -68,7 +68,7 @@ const minDepth = 4 ...@@ -68,7 +68,7 @@ const minDepth = 4
func main() { func main() {
flag.Parse() flag.Parse()
t0 := time.Nanoseconds() t0 := time.Now()
maxDepth := *n maxDepth := *n
if minDepth+2 > *n { if minDepth+2 > *n {
...@@ -93,8 +93,8 @@ func main() { ...@@ -93,8 +93,8 @@ func main() {
} }
fmt.Printf("long lived tree of depth %d\t check: %d\n", maxDepth, longLivedTree.itemCheck()) fmt.Printf("long lived tree of depth %d\t check: %d\n", maxDepth, longLivedTree.itemCheck())
t1 := time.Nanoseconds() t1 := time.Now()
// Standard gotest benchmark output, collected by build dashboard. // Standard gotest benchmark output, collected by build dashboard.
gcstats("BenchmarkTree", *n, t1-t0) gcstats("BenchmarkTree", *n, t1.Sub(t0))
} }
// 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 (
"flag"
"fmt"
"log"
"os"
"runtime"
"runtime/pprof"
"unsafe"
)
const BranchingFactor = 4
type Object struct {
child [BranchingFactor]*Object
}
var (
cpus = flag.Int("cpus", 1, "number of cpus to use")
heapsize = flag.Int64("heapsize", 100*1024*1024, "size of the heap in bytes")
cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
lastPauseNs uint64 = 0
lastFree uint64 = 0
heap *Object
calls [20]int
numobjects int64
)
func buildHeap() {
objsize := int64(unsafe.Sizeof(Object{}))
heap, _ = buildTree(float64(objsize), float64(*heapsize), 0)
fmt.Printf("*** built heap: %.0f MB; (%d objects * %d bytes)\n",
float64(*heapsize)/1048576, numobjects, objsize)
}
func buildTree(objsize, size float64, depth int) (*Object, float64) {
calls[depth]++
x := &Object{}
numobjects++
subtreeSize := (size - objsize) / BranchingFactor
alloc := objsize
for i := 0; i < BranchingFactor && alloc < size; i++ {
c, n := buildTree(objsize, subtreeSize, depth+1)
x.child[i] = c
alloc += n
}
return x, alloc
}
func gc() {
runtime.GC()
runtime.UpdateMemStats()
pause := runtime.MemStats.PauseTotalNs
inuse := runtime.MemStats.Alloc
free := runtime.MemStats.TotalAlloc - inuse
fmt.Printf("gc pause: %8.3f ms; collect: %8.0f MB; heapsize: %8.0f MB\n",
float64(pause-lastPauseNs)/1e6,
float64(free-lastFree)/1048576,
float64(inuse)/1048576)
lastPauseNs = pause
lastFree = free
}
func main() {
flag.Parse()
buildHeap()
runtime.GOMAXPROCS(*cpus)
runtime.UpdateMemStats()
lastPauseNs = runtime.MemStats.PauseTotalNs
lastFree = runtime.MemStats.TotalAlloc - runtime.MemStats.Alloc
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal(err)
}
pprof.StartCPUProfile(f)
defer pprof.StopCPUProfile()
}
for i := 0; i < 10; i++ {
gc()
}
}
include $(GOROOT)/src/Make.inc
TARG=go1
GOFILES=\
dummy.go\
include $(GOROOT)/src/Make.pkg
This source diff could not be displayed because it is too large. You can view the blob instead.
package main
import target "go1"
import "testing"
import "regexp"
var tests = []testing.InternalTest{
}
var benchmarks = []testing.InternalBenchmark{
{"go1.BenchmarkBinaryTree17", target.BenchmarkBinaryTree17},
{"go1.BenchmarkFannkuch11", target.BenchmarkFannkuch11},
{"go1.BenchmarkGobDecode", target.BenchmarkGobDecode},
{"go1.BenchmarkGobEncode", target.BenchmarkGobEncode},
{"go1.BenchmarkGzip", target.BenchmarkGzip},
{"go1.BenchmarkGunzip", target.BenchmarkGunzip},
{"go1.BenchmarkJSONEncode", target.BenchmarkJSONEncode},
{"go1.BenchmarkJSONDecode", target.BenchmarkJSONDecode},
{"go1.BenchmarkRevcomp25M", target.BenchmarkRevcomp25M},
{"go1.BenchmarkTemplate", target.BenchmarkTemplate},
}
var examples = []testing.InternalExample{}
var matchPat string
var matchRe *regexp.Regexp
func matchString(pat, str string) (result bool, err error) {
if matchRe == nil || matchPat != pat {
matchPat = pat
matchRe, err = regexp.Compile(matchPat)
if err != nil {
return
}
}
return matchRe.MatchString(str), nil
}
func main() {
testing.Main(matchString, tests, benchmarks, examples)
}
// 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.
// This benchmark, taken from the shootout, tests garbage collector
// performance by generating and discarding large binary trees.
package go1
import "testing"
type binaryNode struct {
item int
left, right *binaryNode
}
func bottomUpTree(item, depth int) *binaryNode {
if depth <= 0 {
return &binaryNode{item: item}
}
return &binaryNode{item, bottomUpTree(2*item-1, depth-1), bottomUpTree(2*item, depth-1)}
}
func (n *binaryNode) itemCheck() int {
if n.left == nil {
return n.item
}
return n.item + n.left.itemCheck() - n.right.itemCheck()
}
const minDepth = 4
func binarytree(n int) {
maxDepth := n
if minDepth+2 > n {
maxDepth = minDepth + 2
}
stretchDepth := maxDepth + 1
check := bottomUpTree(0, stretchDepth).itemCheck()
//fmt.Printf("stretch tree of depth %d\t check: %d\n", stretchDepth, check)
longLivedTree := bottomUpTree(0, maxDepth)
for depth := minDepth; depth <= maxDepth; depth += 2 {
iterations := 1 << uint(maxDepth-depth+minDepth)
check = 0
for i := 1; i <= iterations; i++ {
check += bottomUpTree(i, depth).itemCheck()
check += bottomUpTree(-i, depth).itemCheck()
}
//fmt.Printf("%d\t trees of depth %d\t check: %d\n", iterations*2, depth, check)
}
longLivedTree.itemCheck()
//fmt.Printf("long lived tree of depth %d\t check: %d\n", maxDepth, longLivedTree.itemCheck())
}
func BenchmarkBinaryTree17(b *testing.B) {
for i := 0; i < b.N; i++ {
binarytree(17)
}
}
package go1
// Nothing to see here: everything is in the _test files.
// 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.
// This benchmark, taken from the shootout, tests array indexing
// and array bounds elimination performance.
package go1
import "testing"
func fannkuch(n int) int {
if n < 1 {
return 0
}
n1 := n - 1
perm := make([]int, n)
perm1 := make([]int, n)
count := make([]int, n)
for i := 0; i < n; i++ {
perm1[i] = i // initial (trivial) permutation
}
r := n
didpr := 0
flipsMax := 0
for {
if didpr < 30 {
didpr++
}
for ; r != 1; r-- {
count[r-1] = r
}
if perm1[0] != 0 && perm1[n1] != n1 {
flips := 0
for i := 1; i < n; i++ { // perm = perm1
perm[i] = perm1[i]
}
k := perm1[0] // cache perm[0] in k
for { // k!=0 ==> k>0
for i, j := 1, k-1; i < j; i, j = i+1, j-1 {
perm[i], perm[j] = perm[j], perm[i]
}
flips++
// Now exchange k (caching perm[0]) and perm[k]... with care!
j := perm[k]
perm[k] = k
k = j
if k == 0 {
break
}
}
if flipsMax < flips {
flipsMax = flips
}
}
for ; r < n; r++ {
// rotate down perm[0..r] by one
perm0 := perm1[0]
for i := 0; i < r; i++ {
perm1[i] = perm1[i+1]
}
perm1[r] = perm0
count[r]--
if count[r] > 0 {
break
}
}
if r == n {
return flipsMax
}
}
return 0
}
func BenchmarkFannkuch11(b *testing.B) {
for i := 0; i < b.N; i++ {
fannkuch(11)
}
}
// 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.
package go1
// Not a benchmark; input for revcomp.
var fasta25m = fasta(25e6)
func fasta(n int) []byte {
out := make(fastaBuffer, 0, 11*n)
iub := []fastaAcid{
{prob: 0.27, sym: 'a'},
{prob: 0.12, sym: 'c'},
{prob: 0.12, sym: 'g'},
{prob: 0.27, sym: 't'},
{prob: 0.02, sym: 'B'},
{prob: 0.02, sym: 'D'},
{prob: 0.02, sym: 'H'},
{prob: 0.02, sym: 'K'},
{prob: 0.02, sym: 'M'},
{prob: 0.02, sym: 'N'},
{prob: 0.02, sym: 'R'},
{prob: 0.02, sym: 'S'},
{prob: 0.02, sym: 'V'},
{prob: 0.02, sym: 'W'},
{prob: 0.02, sym: 'Y'},
}
homosapiens := []fastaAcid{
{prob: 0.3029549426680, sym: 'a'},
{prob: 0.1979883004921, sym: 'c'},
{prob: 0.1975473066391, sym: 'g'},
{prob: 0.3015094502008, sym: 't'},
}
alu := []byte(
"GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG" +
"GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA" +
"CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT" +
"ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA" +
"GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG" +
"AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC" +
"AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA")
out.WriteString(">ONE Homo sapiens alu\n")
fastaRepeat(&out, alu, 2*n)
out.WriteString(">TWO IUB ambiguity codes\n")
fastaRandom(&out, iub, 3*n)
out.WriteString(">THREE Homo sapiens frequency\n")
fastaRandom(&out, homosapiens, 5*n)
return out
}
type fastaBuffer []byte
func (b *fastaBuffer) Flush() {
panic("flush")
}
func (b *fastaBuffer) WriteString(s string) {
p := b.NextWrite(len(s))
copy(p, s)
}
func (b *fastaBuffer) NextWrite(n int) []byte {
p := *b
if len(p)+n > cap(p) {
b.Flush()
p = *b
}
out := p[len(p) : len(p)+n]
*b = p[:len(p)+n]
return out
}
const fastaLine = 60
func fastaRepeat(out *fastaBuffer, alu []byte, n int) {
buf := append(alu, alu...)
off := 0
for n > 0 {
m := n
if m > fastaLine {
m = fastaLine
}
buf1 := out.NextWrite(m + 1)
copy(buf1, buf[off:])
buf1[m] = '\n'
if off += m; off >= len(alu) {
off -= len(alu)
}
n -= m
}
}
const (
fastaLookupSize = 4096
fastaLookupScale float64 = fastaLookupSize - 1
)
var fastaRand uint32 = 42
type fastaAcid struct {
sym byte
prob float64
cprob float64
next *fastaAcid
}
func fastaComputeLookup(acid []fastaAcid) *[fastaLookupSize]*fastaAcid {
var lookup [fastaLookupSize]*fastaAcid
var p float64
for i := range acid {
p += acid[i].prob
acid[i].cprob = p * fastaLookupScale
if i > 0 {
acid[i-1].next = &acid[i]
}
}
acid[len(acid)-1].cprob = 1.0 * fastaLookupScale
j := 0
for i := range lookup {
for acid[j].cprob < float64(i) {
j++
}
lookup[i] = &acid[j]
}
return &lookup
}
func fastaRandom(out *fastaBuffer, acid []fastaAcid, n int) {
const (
IM = 139968
IA = 3877
IC = 29573
)
lookup := fastaComputeLookup(acid)
for n > 0 {
m := n
if m > fastaLine {
m = fastaLine
}
buf := out.NextWrite(m + 1)
f := fastaLookupScale / IM
myrand := fastaRand
for i := 0; i < m; i++ {
myrand = (myrand*IA + IC) % IM
r := float64(int(myrand)) * f
a := lookup[int(r)]
for a.cprob < r {
a = a.next
}
buf[i] = a.sym
}
fastaRand = myrand
buf[m] = '\n'
n -= m
}
}
// 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.
// This benchmark tests gob encoding and decoding performance.
package go1
import (
"bytes"
"encoding/gob"
"encoding/json"
"io/ioutil"
"log"
"reflect"
"testing"
)
var (
gobbytes []byte
gobdata *JSONResponse
)
func gobinit() {
// gobinit is called after json's init,
// because it uses jsondata.
gobdata = gobResponse(&jsondata)
var buf bytes.Buffer
if err := gob.NewEncoder(&buf).Encode(gobdata); err != nil {
panic(err)
}
gobbytes = buf.Bytes()
var r JSONResponse
if err := gob.NewDecoder(bytes.NewBuffer(gobbytes)).Decode(&r); err != nil {
panic(err)
}
if !reflect.DeepEqual(gobdata, &r) {
log.Printf("%v\n%v", jsondata, r)
b, _ := json.Marshal(&jsondata)
br, _ := json.Marshal(&r)
log.Printf("%s\n%s\n", b, br)
panic("gob: encode+decode lost data")
}
}
// gob turns [] into null, so make a copy of the data structure like that
func gobResponse(r *JSONResponse) *JSONResponse {
return &JSONResponse{gobNode(r.Tree), r.Username}
}
func gobNode(n *JSONNode) *JSONNode {
n1 := new(JSONNode)
*n1 = *n
if len(n1.Kids) == 0 {
n1.Kids = nil
} else {
for i, k := range n1.Kids {
n1.Kids[i] = gobNode(k)
}
}
return n1
}
func gobdec() {
if gobbytes == nil {
panic("gobdata not initialized")
}
var r JSONResponse
if err := gob.NewDecoder(bytes.NewBuffer(gobbytes)).Decode(&r); err != nil {
panic(err)
}
_ = r
}
func gobenc() {
if err := gob.NewEncoder(ioutil.Discard).Encode(&gobdata); err != nil {
panic(err)
}
}
func BenchmarkGobDecode(b *testing.B) {
b.SetBytes(int64(len(gobbytes)))
for i := 0; i < b.N; i++ {
gobdec()
}
}
func BenchmarkGobEncode(b *testing.B) {
b.SetBytes(int64(len(gobbytes)))
for i := 0; i < b.N; i++ {
gobenc()
}
}
// 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.
// This benchmark tests gzip and gunzip performance.
package go1
import (
"bytes"
gz "compress/gzip"
"io"
"io/ioutil"
"testing"
)
var (
jsongunz = bytes.Repeat(jsonbytes, 10)
jsongz []byte
)
func init() {
var buf bytes.Buffer
c, err := gz.NewWriter(&buf)
if err != nil {
panic(err)
}
c.Write(jsongunz)
c.Close()
jsongz = buf.Bytes()
}
func gzip() {
c, err := gz.NewWriter(ioutil.Discard)
if err != nil {
panic(err)
}
if _, err := c.Write(jsongunz); err != nil {
panic(err)
}
if err := c.Close(); err != nil {
panic(err)
}
}
func gunzip() {
r, err := gz.NewReader(bytes.NewBuffer(jsongz))
if err != nil {
panic(err)
}
if _, err := io.Copy(ioutil.Discard, r); err != nil {
panic(err)
}
r.Close()
}
func BenchmarkGzip(b *testing.B) {
b.SetBytes(int64(len(jsongunz)))
for i := 0; i < b.N; i++ {
gzip()
}
}
func BenchmarkGunzip(b *testing.B) {
b.SetBytes(int64(len(jsongunz)))
for i := 0; i < b.N; i++ {
gunzip()
}
}
// 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.
// This benchmark tests JSON encoding and decoding performance.
package go1
import (
"compress/bzip2"
"encoding/base64"
"encoding/json"
"io"
"io/ioutil"
"strings"
"testing"
)
var (
jsonbytes []byte
jsondata JSONResponse
)
func init() {
var r io.Reader
r = strings.NewReader(jsonbz2_base64)
r = base64.NewDecoder(base64.StdEncoding, r)
r = bzip2.NewReader(r)
b, err := ioutil.ReadAll(r)
if err != nil {
panic(err)
}
jsonbytes = b
if err := json.Unmarshal(jsonbytes, &jsondata); err != nil {
panic(err)
}
gobinit()
}
type JSONResponse struct {
Tree *JSONNode `json:"tree"`
Username string `json:"username"`
}
type JSONNode struct {
Name string `json:"name"`
Kids []*JSONNode `json:"kids"`
CLWeight float64 `json:"cl_weight"`
Touches int `json:"touches"`
MinT int64 `json:"min_t"`
MaxT int64 `json:"max_t"`
MeanT int64 `json:"mean_t"`
}
func jsondec() {
var r JSONResponse
if err := json.Unmarshal(jsonbytes, &r); err != nil {
panic(err)
}
_ = r
}
func jsonenc() {
buf, err := json.Marshal(&jsondata)
if err != nil {
panic(err)
}
_ = buf
}
func BenchmarkJSONEncode(b *testing.B) {
b.SetBytes(int64(len(jsonbytes)))
for i := 0; i < b.N; i++ {
jsonenc()
}
}
func BenchmarkJSONDecode(b *testing.B) {
b.SetBytes(int64(len(jsonbytes)))
for i := 0; i < b.N; i++ {
jsondec()
}
}
This source diff could not be displayed because it is too large. You can view the blob instead.
// 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.
// This benchmark, taken from the shootout, tests array indexing
// and array bounds elimination performance.
package go1
import (
"bufio"
"bytes"
"io/ioutil"
"testing"
)
var revCompTable = [256]uint8{
'A': 'T', 'a': 'T',
'C': 'G', 'c': 'G',
'G': 'C', 'g': 'C',
'T': 'A', 't': 'A',
'U': 'A', 'u': 'A',
'M': 'K', 'm': 'K',
'R': 'Y', 'r': 'Y',
'W': 'W', 'w': 'W',
'S': 'S', 's': 'S',
'Y': 'R', 'y': 'R',
'K': 'M', 'k': 'M',
'V': 'B', 'v': 'B',
'H': 'D', 'h': 'D',
'D': 'H', 'd': 'H',
'B': 'V', 'b': 'V',
'N': 'N', 'n': 'N',
}
func revcomp(data []byte) {
in := bufio.NewReader(bytes.NewBuffer(data))
out := ioutil.Discard
buf := make([]byte, 1024*1024)
line, err := in.ReadSlice('\n')
for err == nil {
out.Write(line)
// Accumulate reversed complement in buf[w:]
nchar := 0
w := len(buf)
for {
line, err = in.ReadSlice('\n')
if err != nil || line[0] == '>' {
break
}
line = line[0 : len(line)-1]
nchar += len(line)
if len(line)+nchar/60+128 >= w {
nbuf := make([]byte, len(buf)*5)
copy(nbuf[len(nbuf)-len(buf):], buf)
w += len(nbuf) - len(buf)
buf = nbuf
}
// This loop is the bottleneck.
for _, c := range line {
w--
buf[w] = revCompTable[c]
}
}
// Copy down to beginning of buffer, inserting newlines.
// The loop left room for the newlines and 128 bytes of padding.
i := 0
for j := w; j < len(buf); j += 60 {
n := copy(buf[i:i+60], buf[j:])
buf[i+n] = '\n'
i += n + 1
}
out.Write(buf[0:i])
}
}
func BenchmarkRevcomp25M(b *testing.B) {
b.SetBytes(int64(len(fasta25m)))
for i := 0; i < b.N; i++ {
revcomp(fasta25m)
}
}
// 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.
// This benchmark tests text/template throughput,
// converting a large data structure with a simple template.
package go1
import (
"bytes"
"io/ioutil"
"strings"
"testing"
"text/template"
)
// After removing \t and \n this generates identical output to
// json.Marshal, making it easy to test for correctness.
const tmplText = `
{
"tree":{{template "node" .Tree}},
"username":"{{.Username}}"
}
{{define "node"}}
{
"name":"{{.Name}}",
"kids":[
{{range $i, $k := .Kids}}
{{if $i}}
,
{{end}}
{{template "node" $k}}
{{end}}
],
"cl_weight":{{.CLWeight}},
"touches":{{.Touches}},
"min_t":{{.MinT}},
"max_t":{{.MaxT}},
"mean_t":{{.MeanT}}
}
{{end}}
`
func stripTabNL(r rune) rune {
if r == '\t' || r == '\n' {
return -1
}
return r
}
var tmpl = template.Must(template.New("main").Parse(strings.Map(stripTabNL, tmplText)))
func init() {
var buf bytes.Buffer
if err := tmpl.Execute(&buf, &jsondata); err != nil {
panic(err)
}
if !bytes.Equal(buf.Bytes(), jsonbytes) {
println(buf.Len(), len(jsonbytes))
panic("wrong output")
}
}
func tmplexec() {
if err := tmpl.Execute(ioutil.Discard, &jsondata); err != nil {
panic(err)
}
}
func BenchmarkTemplate(b *testing.B) {
b.SetBytes(int64(len(jsonbytes)))
for i := 0; i < b.N; i++ {
tmplexec()
}
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# 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.
include ../../src/Make.inc include ../../../src/Make.inc
all: all:
@echo "make clean or timing" @echo "make clean or timing"
......
...@@ -49,20 +49,20 @@ const ( ...@@ -49,20 +49,20 @@ const (
) )
var complement = [...]int{ var complement = [...]int{
red | red<<2: red, red | red<<2: red,
red | yellow<<2: blue, red | yellow<<2: blue,
red | blue<<2: yellow, red | blue<<2: yellow,
yellow | red<<2: blue, yellow | red<<2: blue,
yellow | yellow<<2: yellow, yellow | yellow<<2: yellow,
yellow | blue<<2: red, yellow | blue<<2: red,
blue | red<<2: yellow, blue | red<<2: yellow,
blue | yellow<<2: red, blue | yellow<<2: red,
blue | blue<<2: blue, blue | blue<<2: blue,
} }
var colname = [...]string{ var colname = [...]string{
blue: "blue", blue: "blue",
red: "red", red: "red",
yellow: "yellow", yellow: "yellow",
} }
......
...@@ -70,7 +70,7 @@ const ( ...@@ -70,7 +70,7 @@ const (
IA = 3877 IA = 3877
IC = 29573 IC = 29573
LookupSize = 4096 LookupSize = 4096
LookupScale float64 = LookupSize - 1 LookupScale float64 = LookupSize - 1
) )
...@@ -178,7 +178,6 @@ func main() { ...@@ -178,7 +178,6 @@ func main() {
Random(homosapiens, 5**n) Random(homosapiens, 5**n)
} }
type buffer []byte type buffer []byte
func (b *buffer) Flush() { func (b *buffer) Flush() {
......
...@@ -43,7 +43,6 @@ import ( ...@@ -43,7 +43,6 @@ import (
var max_solutions = flag.Int("n", 2100, "maximum number of solutions") var max_solutions = flag.Int("n", 2100, "maximum number of solutions")
func boolInt(b bool) int8 { func boolInt(b bool) int8 {
if b { if b {
return 1 return 1
...@@ -115,7 +114,6 @@ var piece_def = [10][4]int8{ ...@@ -115,7 +114,6 @@ var piece_def = [10][4]int8{
[4]int8{E, E, E, SW}, [4]int8{E, E, E, SW},
} }
/* To minimize the amount of work done in the recursive solve function below, /* To minimize the amount of work done in the recursive solve function below,
* I'm going to allocate enough space for all legal rotations of each piece * I'm going to allocate enough space for all legal rotations of each piece
* at each position on the board. That's 10 pieces x 50 board positions x * at each position on the board. That's 10 pieces x 50 board positions x
...@@ -138,7 +136,6 @@ func rotate(dir int8) int8 { return (dir + 2) % PIVOT } ...@@ -138,7 +136,6 @@ func rotate(dir int8) int8 { return (dir + 2) % PIVOT }
/* Returns the direction flipped on the horizontal axis */ /* Returns the direction flipped on the horizontal axis */
func flip(dir int8) int8 { return (PIVOT - dir) % PIVOT } func flip(dir int8) int8 { return (PIVOT - dir) % PIVOT }
/* Returns the new cell index from the specified cell in the /* Returns the new cell index from the specified cell in the
* specified direction. The index is only valid if the * specified direction. The index is only valid if the
* starting cell and direction have been checked by the * starting cell and direction have been checked by the
...@@ -322,7 +319,6 @@ func record_piece(piece int, minimum int8, first_empty int8, piece_mask uint64) ...@@ -322,7 +319,6 @@ func record_piece(piece int, minimum int8, first_empty int8, piece_mask uint64)
piece_counts[piece][minimum]++ piece_counts[piece][minimum]++
} }
/* Fill the entire board going cell by cell. If any cells are "trapped" /* Fill the entire board going cell by cell. If any cells are "trapped"
* they will be left alone. * they will be left alone.
*/ */
...@@ -351,7 +347,6 @@ func fill_contiguous_space(board []int8, index int8) { ...@@ -351,7 +347,6 @@ func fill_contiguous_space(board []int8, index int8) {
} }
} }
/* To thin the number of pieces, I calculate if any of them trap any empty /* To thin the number of pieces, I calculate if any of them trap any empty
* cells at the edges. There are only a handful of exceptions where the * cells at the edges. There are only a handful of exceptions where the
* the board can be solved with the trapped cells. For example: piece 8 can * the board can be solved with the trapped cells. For example: piece 8 can
...@@ -382,7 +377,6 @@ func has_island(cell []int8, piece int) bool { ...@@ -382,7 +377,6 @@ func has_island(cell []int8, piece int) bool {
return true return true
} }
/* Calculate all six rotations of the specified piece at the specified index. /* Calculate all six rotations of the specified piece at the specified index.
* We calculate only half of piece 3's rotations. This is because any solution * We calculate only half of piece 3's rotations. This is because any solution
* found has an identical solution rotated 180 degrees. Thus we can reduce the * found has an identical solution rotated 180 degrees. Thus we can reduce the
...@@ -417,7 +411,6 @@ func calc_pieces() { ...@@ -417,7 +411,6 @@ func calc_pieces() {
} }
} }
/* Calculate all 32 possible states for a 5-bit row and all rows that will /* Calculate all 32 possible states for a 5-bit row and all rows that will
* create islands that follow any of the 32 possible rows. These pre- * create islands that follow any of the 32 possible rows. These pre-
* calculated 5-bit rows will be used to find islands in a partially solved * calculated 5-bit rows will be used to find islands in a partially solved
...@@ -530,7 +523,6 @@ func calc_rows() { ...@@ -530,7 +523,6 @@ func calc_rows() {
} }
} }
/* Calculate islands while solving the board. /* Calculate islands while solving the board.
*/ */
func boardHasIslands(cell int8) int8 { func boardHasIslands(cell int8) int8 {
...@@ -545,7 +537,6 @@ func boardHasIslands(cell int8) int8 { ...@@ -545,7 +537,6 @@ func boardHasIslands(cell int8) int8 {
return bad_even_triple[current_triple] return bad_even_triple[current_triple]
} }
/* The recursive solve algorithm. Try to place each permutation in the upper- /* The recursive solve algorithm. Try to place each permutation in the upper-
* leftmost empty cell. Mark off available pieces as it goes along. * leftmost empty cell. Mark off available pieces as it goes along.
* Because the board is a bit mask, the piece number and bit mask must be saved * Because the board is a bit mask, the piece number and bit mask must be saved
......
...@@ -125,39 +125,39 @@ func (sys System) advance(dt float64) { ...@@ -125,39 +125,39 @@ func (sys System) advance(dt float64) {
var ( var (
jupiter = Body{ jupiter = Body{
x: 4.84143144246472090e+00, x: 4.84143144246472090e+00,
y: -1.16032004402742839e+00, y: -1.16032004402742839e+00,
z: -1.03622044471123109e-01, z: -1.03622044471123109e-01,
vx: 1.66007664274403694e-03 * daysPerYear, vx: 1.66007664274403694e-03 * daysPerYear,
vy: 7.69901118419740425e-03 * daysPerYear, vy: 7.69901118419740425e-03 * daysPerYear,
vz: -6.90460016972063023e-05 * daysPerYear, vz: -6.90460016972063023e-05 * daysPerYear,
mass: 9.54791938424326609e-04 * solarMass, mass: 9.54791938424326609e-04 * solarMass,
} }
saturn = Body{ saturn = Body{
x: 8.34336671824457987e+00, x: 8.34336671824457987e+00,
y: 4.12479856412430479e+00, y: 4.12479856412430479e+00,
z: -4.03523417114321381e-01, z: -4.03523417114321381e-01,
vx: -2.76742510726862411e-03 * daysPerYear, vx: -2.76742510726862411e-03 * daysPerYear,
vy: 4.99852801234917238e-03 * daysPerYear, vy: 4.99852801234917238e-03 * daysPerYear,
vz: 2.30417297573763929e-05 * daysPerYear, vz: 2.30417297573763929e-05 * daysPerYear,
mass: 2.85885980666130812e-04 * solarMass, mass: 2.85885980666130812e-04 * solarMass,
} }
uranus = Body{ uranus = Body{
x: 1.28943695621391310e+01, x: 1.28943695621391310e+01,
y: -1.51111514016986312e+01, y: -1.51111514016986312e+01,
z: -2.23307578892655734e-01, z: -2.23307578892655734e-01,
vx: 2.96460137564761618e-03 * daysPerYear, vx: 2.96460137564761618e-03 * daysPerYear,
vy: 2.37847173959480950e-03 * daysPerYear, vy: 2.37847173959480950e-03 * daysPerYear,
vz: -2.96589568540237556e-05 * daysPerYear, vz: -2.96589568540237556e-05 * daysPerYear,
mass: 4.36624404335156298e-05 * solarMass, mass: 4.36624404335156298e-05 * solarMass,
} }
neptune = Body{ neptune = Body{
x: 1.53796971148509165e+01, x: 1.53796971148509165e+01,
y: -2.59193146099879641e+01, y: -2.59193146099879641e+01,
z: 1.79258772950371181e-01, z: 1.79258772950371181e-01,
vx: 2.68067772490389322e-03 * daysPerYear, vx: 2.68067772490389322e-03 * daysPerYear,
vy: 1.62824170038242295e-03 * daysPerYear, vy: 1.62824170038242295e-03 * daysPerYear,
vz: -9.51592254519715870e-05 * daysPerYear, vz: -9.51592254519715870e-05 * daysPerYear,
mass: 5.15138902046611451e-05 * solarMass, mass: 5.15138902046611451e-05 * solarMass,
} }
sun = Body{ sun = Body{
......
...@@ -38,9 +38,9 @@ POSSIBILITY OF SUCH DAMAGE. ...@@ -38,9 +38,9 @@ POSSIBILITY OF SUCH DAMAGE.
package main package main
import ( import (
"big"
"flag" "flag"
"fmt" "fmt"
"math/big"
) )
var n = flag.Int("n", 27, "number of digits") var n = flag.Int("n", 27, "number of digits")
......
...@@ -39,8 +39,8 @@ import ( ...@@ -39,8 +39,8 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"runtime"
"regexp" "regexp"
"runtime"
) )
var variants = []string{ var variants = []string{
......
...@@ -52,7 +52,7 @@ func f(i int, in <-chan int, out chan<- int) { ...@@ -52,7 +52,7 @@ func f(i int, in <-chan int, out chan<- int) {
fmt.Printf("%d\n", i) fmt.Printf("%d\n", i)
os.Exit(0) os.Exit(0)
} }
out <- n-1 out <- n - 1
} }
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
set -e set -e
eval $(gomake --no-print-directory -f ../../src/Make.inc go-env) eval $(gomake --no-print-directory -f ../../../src/Make.inc go-env)
PATH=.:$PATH PATH=.:$PATH
havegccgo=false havegccgo=false
......
...@@ -101,6 +101,46 @@ func main() { ...@@ -101,6 +101,46 @@ func main() {
} }
h(a, b) h(a, b)
m()
}
type I interface {
M(_ int, y int)
}
type TI struct{}
func (TI) M(x int, y int) {
if x != y {
println("invalid M call:", x, y)
panic("bad M")
}
}
var fp = func(_ int, y int) {}
func init() {
fp = fp1
}
func fp1(x, y int) {
if x != y {
println("invalid fp1 call:", x, y)
panic("bad fp1")
}
}
func m() {
var i I
i = TI{}
i.M(1, 1)
i.M(2, 2)
fp(1, 1)
fp(2, 2)
} }
// useless but legal // useless but legal
...@@ -120,3 +160,4 @@ func _() { ...@@ -120,3 +160,4 @@ func _() {
func ff() { func ff() {
var _ int = 1 var _ int = 1
} }
// echo bug395 is broken # takes 90+ seconds to break
// # $G $D/$F.go || echo bug395
// 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 1909
// Would OOM due to exponential recursion on Foo's expanded methodset in nodefmt
package test
type Foo interface {
Bar() interface {
Foo
}
Baz() interface {
Foo
}
Bug() interface {
Foo
}
}
...@@ -82,5 +82,4 @@ func main() { ...@@ -82,5 +82,4 @@ func main() {
// However, the result of the bug linked to at the top is that we'll // However, the result of the bug linked to at the top is that we'll
// end up panicking with: "throw: bad g->status in ready". // end up panicking with: "throw: bad g->status in ready".
recver(cmux) recver(cmux)
print("PASS\n")
} }
...@@ -279,5 +279,4 @@ func main() { ...@@ -279,5 +279,4 @@ func main() {
<-sync <-sync
} }
} }
print("PASS\n")
} }
...@@ -48,4 +48,11 @@ func main() { ...@@ -48,4 +48,11 @@ func main() {
case x := <-cs: // ERROR "receive" case x := <-cs: // ERROR "receive"
_ = x _ = x
} }
for _ = range cs {// ERROR "receive"
}
close(c)
close(cs)
close(cr) // ERROR "receive"
} }
// $G $D/$F.go && $L $F.$A && ./$A.out
// 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 select when discarding a value.
package main
import "runtime"
func recv1(c <-chan int) {
<-c
}
func recv2(c <-chan int) {
select {
case <-c:
}
}
func recv3(c <-chan int) {
c2 := make(chan int)
select {
case <-c:
case <-c2:
}
}
func send1(recv func(<-chan int)) {
c := make(chan int)
go recv(c)
runtime.Gosched()
c <- 1
}
func send2(recv func(<-chan int)) {
c := make(chan int)
go recv(c)
runtime.Gosched()
select {
case c <- 1:
}
}
func send3(recv func(<-chan int)) {
c := make(chan int)
go recv(c)
runtime.Gosched()
c2 := make(chan int)
select {
case c <- 1:
case c2 <- 1:
}
}
func main() {
send1(recv1)
send2(recv1)
send3(recv1)
send1(recv2)
send2(recv2)
send3(recv2)
send1(recv3)
send2(recv3)
send3(recv3)
}
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
package main package main
import "runtime"
var c = make(chan int) var c = make(chan int)
func check(a []int) { func check(a []int) {
...@@ -77,6 +79,8 @@ func h() { ...@@ -77,6 +79,8 @@ func h() {
func newfunc() func(int) int { return func(x int) int { return x } } func newfunc() func(int) int { return func(x int) int { return x } }
func main() { func main() {
var fail bool
go f() go f()
check([]int{1, 4, 5, 4}) check([]int{1, 4, 5, 4})
...@@ -88,13 +92,26 @@ func main() { ...@@ -88,13 +92,26 @@ func main() {
go h() go h()
check([]int{100, 200, 101, 201, 500, 101, 201, 500}) check([]int{100, 200, 101, 201, 500, 101, 201, 500})
runtime.UpdateMemStats()
n0 := runtime.MemStats.Mallocs
x, y := newfunc(), newfunc() x, y := newfunc(), newfunc()
if x(1) != 1 || y(2) != 2 { if x(1) != 1 || y(2) != 2 {
println("newfunc returned broken funcs") println("newfunc returned broken funcs")
panic("fail") fail = true
}
runtime.UpdateMemStats()
if n0 != runtime.MemStats.Mallocs {
println("newfunc allocated unexpectedly")
fail = true
} }
ff(1) ff(1)
if fail {
panic("fail")
}
} }
func ff(x int) { func ff(x int) {
......
// $G $D/$F.go && $L $F.$A && ./$A.out
// 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 "unsafe"
var global bool
func use(b bool) { global = b }
func stringptr(s string) uintptr { return *(*uintptr)(unsafe.Pointer(&s)) }
func isfalse(b bool) {
if b {
// stack will explain where
panic("wanted false, got true")
}
}
func istrue(b bool) {
if !b {
// stack will explain where
panic("wanted true, got false")
}
}
type T *int
func main() {
var a []int
var b map[string]int
var c string = "hello"
var d string = "hel" // try to get different pointer
d = d + "lo"
if stringptr(c) == stringptr(d) {
panic("compiler too smart -- got same string")
}
var e = make(chan int)
var ia interface{} = a
var ib interface{} = b
var ic interface{} = c
var id interface{} = d
var ie interface{} = e
// these comparisons are okay because
// string compare is okay and the others
// are comparisons where the types differ.
isfalse(ia == ib)
isfalse(ia == ic)
isfalse(ia == id)
isfalse(ib == ic)
isfalse(ib == id)
istrue(ic == id)
istrue(ie == ie)
istrue(ia != ib)
istrue(ia != ic)
istrue(ia != id)
istrue(ib != ic)
istrue(ib != id)
isfalse(ic != id)
isfalse(ie != ie)
// these are not okay, because there is no comparison on slices or maps.
//isfalse(a == ib)
//isfalse(a == ic)
//isfalse(a == id)
//isfalse(b == ic)
//isfalse(b == id)
istrue(c == id)
istrue(e == ie)
//isfalse(ia == b)
isfalse(ia == c)
isfalse(ia == d)
isfalse(ib == c)
isfalse(ib == d)
istrue(ic == d)
istrue(ie == e)
//istrue(a != ib)
//istrue(a != ic)
//istrue(a != id)
//istrue(b != ic)
//istrue(b != id)
isfalse(c != id)
isfalse(e != ie)
//istrue(ia != b)
istrue(ia != c)
istrue(ia != d)
istrue(ib != c)
istrue(ib != d)
isfalse(ic != d)
isfalse(ie != e)
// 6g used to let this go through as true.
var g uint64 = 123
var h int64 = 123
var ig interface{} = g
var ih interface{} = h
isfalse(ig == ih)
istrue(ig != ih)
// map of interface should use == on interface values,
// not memory.
var m = make(map[interface{}]int)
m[ic] = 1
m[id] = 2
if m[c] != 2 {
println("m[c] = ", m[c])
panic("bad m[c]")
}
// non-interface comparisons
{
c := make(chan int)
c1 := (<-chan int)(c)
c2 := (chan<- int)(c)
istrue(c == c1)
istrue(c == c2)
istrue(c1 == c)
istrue(c2 == c)
isfalse(c != c1)
isfalse(c != c2)
isfalse(c1 != c)
isfalse(c2 != c)
d := make(chan int)
isfalse(c == d)
isfalse(d == c)
isfalse(d == c1)
isfalse(d == c2)
isfalse(c1 == d)
isfalse(c2 == d)
istrue(c != d)
istrue(d != c)
istrue(d != c1)
istrue(d != c2)
istrue(c1 != d)
istrue(c2 != d)
}
// named types vs not
{
var x = new(int)
var y T
var z T = x
isfalse(x == y)
istrue(x == z)
isfalse(y == z)
isfalse(y == x)
istrue(z == x)
isfalse(z == y)
istrue(x != y)
isfalse(x != z)
istrue(y != z)
istrue(y != x)
isfalse(z != x)
istrue(z != y)
}
// structs
{
var x = struct {
x int
y string
}{1, "hi"}
var y = struct {
x int
y string
}{2, "bye"}
var z = struct {
x int
y string
}{1, "hi"}
isfalse(x == y)
isfalse(y == x)
isfalse(y == z)
isfalse(z == y)
istrue(x == z)
istrue(z == x)
istrue(x != y)
istrue(y != x)
istrue(y != z)
istrue(z != y)
isfalse(x != z)
isfalse(z != x)
var m = make(map[struct {
x int
y string
}]int)
m[x] = 10
m[y] = 20
m[z] = 30
istrue(m[x] == 30)
istrue(m[y] == 20)
istrue(m[z] == 30)
istrue(m[x] != 10)
isfalse(m[x] != 30)
isfalse(m[y] != 20)
isfalse(m[z] != 30)
isfalse(m[x] == 10)
var m1 = make(map[struct {
x int
y string
}]struct {
x int
y string
})
m1[x] = x
m1[y] = y
m1[z] = z
istrue(m1[x] == z)
istrue(m1[y] == y)
istrue(m1[z] == z)
istrue(m1[x] == x)
isfalse(m1[x] != z)
isfalse(m1[y] != y)
isfalse(m1[z] != z)
isfalse(m1[x] != x)
var ix, iy, iz interface{} = x, y, z
isfalse(ix == iy)
isfalse(iy == ix)
isfalse(iy == iz)
isfalse(iz == iy)
istrue(ix == iz)
istrue(iz == ix)
isfalse(x == iy)
isfalse(y == ix)
isfalse(y == iz)
isfalse(z == iy)
istrue(x == iz)
istrue(z == ix)
isfalse(ix == y)
isfalse(iy == x)
isfalse(iy == z)
isfalse(iz == y)
istrue(ix == z)
istrue(iz == x)
istrue(ix != iy)
istrue(iy != ix)
istrue(iy != iz)
istrue(iz != iy)
isfalse(ix != iz)
isfalse(iz != ix)
istrue(x != iy)
istrue(y != ix)
istrue(y != iz)
istrue(z != iy)
isfalse(x != iz)
isfalse(z != ix)
istrue(ix != y)
istrue(iy != x)
istrue(iy != z)
istrue(iz != y)
isfalse(ix != z)
isfalse(iz != x)
}
// arrays
{
var x = [2]string{"1", "hi"}
var y = [2]string{"2", "bye"}
var z = [2]string{"1", "hi"}
isfalse(x == y)
isfalse(y == x)
isfalse(y == z)
isfalse(z == y)
istrue(x == z)
istrue(z == x)
istrue(x != y)
istrue(y != x)
istrue(y != z)
istrue(z != y)
isfalse(x != z)
isfalse(z != x)
var m = make(map[[2]string]int)
m[x] = 10
m[y] = 20
m[z] = 30
istrue(m[x] == 30)
istrue(m[y] == 20)
istrue(m[z] == 30)
isfalse(m[x] != 30)
isfalse(m[y] != 20)
isfalse(m[z] != 30)
var ix, iy, iz interface{} = x, y, z
isfalse(ix == iy)
isfalse(iy == ix)
isfalse(iy == iz)
isfalse(iz == iy)
istrue(ix == iz)
istrue(iz == ix)
isfalse(x == iy)
isfalse(y == ix)
isfalse(y == iz)
isfalse(z == iy)
istrue(x == iz)
istrue(z == ix)
isfalse(ix == y)
isfalse(iy == x)
isfalse(iy == z)
isfalse(iz == y)
istrue(ix == z)
istrue(iz == x)
istrue(ix != iy)
istrue(iy != ix)
istrue(iy != iz)
istrue(iz != iy)
isfalse(ix != iz)
isfalse(iz != ix)
istrue(x != iy)
istrue(y != ix)
istrue(y != iz)
istrue(z != iy)
isfalse(x != iz)
isfalse(z != ix)
istrue(ix != y)
istrue(iy != x)
istrue(iy != z)
istrue(iz != y)
isfalse(ix != z)
isfalse(iz != x)
}
shouldPanic(p1)
shouldPanic(p2)
shouldPanic(p3)
shouldPanic(p4)
}
func p1() {
var a []int
var ia interface{} = a
use(ia == ia)
}
func p2() {
var b []int
var ib interface{} = b
use(ib == ib)
}
func p3() {
var a []int
var ia interface{} = a
var m = make(map[interface{}]int)
m[ia] = 1
}
func p4() {
var b []int
var ib interface{} = b
var m = make(map[interface{}]int)
m[ib] = 1
}
func shouldPanic(f func()) {
defer func() {
if recover() == nil {
panic("function should panic")
}
}()
f()
}
// $G $D/$F.go && $L $F.$A && ! ./$A.out
// 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
func use(bool) { }
func main() {
var a []int
var ia interface{} = a
use(ia == ia)
}
// $G $D/$F.go && $L $F.$A && ! ./$A.out
// 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
func use(bool) { }
func main() {
var b []int
var ib interface{} = b
use(ib == ib)
}
// $G $D/$F.go && $L $F.$A && ! ./$A.out
// 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
func main() {
var a []int
var ia interface{} = a
var m = make(map[interface{}] int)
m[ia] = 1
}
// $G $D/$F.go && $L $F.$A && ! ./$A.out
// 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
func main() {
var b []int
var ib interface{} = b
var m = make(map[interface{}] int)
m[ib] = 1
}
...@@ -31,6 +31,18 @@ func eq(a []*R) { ...@@ -31,6 +31,18 @@ func eq(a []*R) {
} }
} }
func teq(t *T, n int) {
for i := 0; i < n; i++ {
if t == nil || t.i != i {
panic("bad")
}
t = t.next
}
if t != nil {
panic("bad")
}
}
type P struct { type P struct {
a, b int a, b int
} }
...@@ -46,6 +58,9 @@ func main() { ...@@ -46,6 +58,9 @@ func main() {
var tp *T var tp *T
tp = &T{0, 7.2, "hi", &t} tp = &T{0, 7.2, "hi", &t}
tl := &T{i: 0, next: &T{i: 1, next: &T{i: 2, next: &T{i: 3, next: &T{i: 4}}}}}
teq(tl, 5)
a1 := []int{1, 2, 3} a1 := []int{1, 2, 3}
if len(a1) != 3 { if len(a1) != 3 {
panic("a1") panic("a1")
...@@ -93,6 +108,7 @@ func main() { ...@@ -93,6 +108,7 @@ func main() {
} }
eq([]*R{itor(0), itor(1), itor(2), itor(3), itor(4), itor(5)}) eq([]*R{itor(0), itor(1), itor(2), itor(3), itor(4), itor(5)})
eq([]*R{{0}, {1}, {2}, {3}, {4}, {5}})
p1 := NewP(1, 2) p1 := NewP(1, 2)
p2 := NewP(1, 2) p2 := NewP(1, 2)
......
// errchk $G -e $D/$F.go
// 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.
package main
var m map[int][3]int
func f() [3]int
func fp() *[3]int
var mp map[int]*[3]int
var (
_ = [3]int{1, 2, 3}[:] // ERROR "slice of unaddressable value"
_ = m[0][:] // ERROR "slice of unaddressable value"
_ = f()[:] // ERROR "slice of unaddressable value"
// these are okay because they are slicing a pointer to an array
_ = (&[3]int{1, 2, 3})[:]
_ = mp[0][:]
_ = fp()[:]
)
type T struct {
i int
f float64
s string
next *T
}
var (
_ = &T{0, 0, "", nil} // ok
_ = &T{i: 0, f: 0, s: "", next: {}} // ERROR "missing type in composite literal|omit types within composite literal"
_ = &T{0, 0, "", {}} // ERROR "missing type in composite literal|omit types within composite literal"
)
// errchk $G -e $D/$F.go
// 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.
package main
type Tbyte []byte
type Trune []rune
type Tint64 []int64
type Tstring string
func main() {
s := "hello"
sb := []byte("hello")
sr := []rune("hello")
si := []int64{'h', 'e', 'l', 'l', 'o'}
ts := Tstring(s)
tsb := Tbyte(sb)
tsr := Trune(sr)
tsi := Tint64(si)
_ = string(s)
_ = []byte(s)
_ = []rune(s)
_ = []int64(s) // ERROR "cannot convert.*\[\]int64|invalid type conversion"
_ = Tstring(s)
_ = Tbyte(s)
_ = Trune(s)
_ = Tint64(s) // ERROR "cannot convert.*Tint64|invalid type conversion"
_ = string(sb)
_ = []byte(sb)
_ = []rune(sb) // ERROR "cannot convert.*\[\]rune|invalid type conversion"
_ = []int64(sb) // ERROR "cannot convert.*\[\]int64|invalid type conversion"
_ = Tstring(sb)
_ = Tbyte(sb)
_ = Trune(sb) // ERROR "cannot convert.*Trune|invalid type conversion"
_ = Tint64(sb) // ERROR "cannot convert.*Tint64|invalid type conversion"
_ = string(sr)
_ = []byte(sr) // ERROR "cannot convert.*\[\]byte|invalid type conversion"
_ = []rune(sr)
_ = []int64(sr) // ERROR "cannot convert.*\[\]int64|invalid type conversion"
_ = Tstring(sr)
_ = Tbyte(sr) // ERROR "cannot convert.*Tbyte|invalid type conversion"
_ = Trune(sr)
_ = Tint64(sr) // ERROR "cannot convert.*Tint64|invalid type conversion"
_ = string(si) // ERROR "cannot convert.* string|invalid type conversion"
_ = []byte(si) // ERROR "cannot convert.*\[\]byte|invalid type conversion"
_ = []rune(si) // ERROR "cannot convert.*\[\]rune|invalid type conversion"
_ = []int64(si)
_ = Tstring(si) // ERROR "cannot convert.*Tstring|invalid type conversion"
_ = Tbyte(si) // ERROR "cannot convert.*Tbyte|invalid type conversion"
_ = Trune(si) // ERROR "cannot convert.*Trune|invalid type conversion"
_ = Tint64(si)
_ = string(ts)
_ = []byte(ts)
_ = []rune(ts)
_ = []int64(ts) // ERROR "cannot convert.*\[\]int64|invalid type conversion"
_ = Tstring(ts)
_ = Tbyte(ts)
_ = Trune(ts)
_ = Tint64(ts) // ERROR "cannot convert.*Tint64|invalid type conversion"
_ = string(tsb)
_ = []byte(tsb)
_ = []rune(tsb) // ERROR "cannot convert.*\[\]rune|invalid type conversion"
_ = []int64(tsb) // ERROR "cannot convert.*\[\]int64|invalid type conversion"
_ = Tstring(tsb)
_ = Tbyte(tsb)
_ = Trune(tsb) // ERROR "cannot convert.*Trune|invalid type conversion"
_ = Tint64(tsb) // ERROR "cannot convert.*Tint64|invalid type conversion"
_ = string(tsr)
_ = []byte(tsr) // ERROR "cannot convert.*\[\]byte|invalid type conversion"
_ = []rune(tsr)
_ = []int64(tsr) // ERROR "cannot convert.*\[\]int64|invalid type conversion"
_ = Tstring(tsr)
_ = Tbyte(tsr) // ERROR "cannot convert.*Tbyte|invalid type conversion"
_ = Trune(tsr)
_ = Tint64(tsr) // ERROR "cannot convert.*Tint64|invalid type conversion"
_ = string(tsi) // ERROR "cannot convert.* string|invalid type conversion"
_ = []byte(tsi) // ERROR "cannot convert.*\[\]byte|invalid type conversion"
_ = []rune(tsi) // ERROR "cannot convert.*\[\]rune|invalid type conversion"
_ = []int64(tsi)
_ = Tstring(tsi) // ERROR "cannot convert.*Tstring|invalid type conversion"
_ = Tbyte(tsi) // ERROR "cannot convert.*Tbyte|invalid type conversion"
_ = Trune(tsi) // ERROR "cannot convert.*Trune|invalid type conversion"
_ = Tint64(tsi)
}
// $G $D/$F.go && $L $F.$A && ./$A.out >tmp.go &&
// $G tmp.go && $L tmp.$A && ./$A.out
// rm -f tmp.go
// 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 source files and strings containing \r and \r\n.
package main
import (
"fmt"
"strings"
)
func main() {
prog = strings.Replace(prog, "BQ", "`", -1)
prog = strings.Replace(prog, "CR", "\r", -1)
fmt.Print(prog)
}
var prog = `
package main
CR
import "fmt"
var CR s = "hello\n" + CR
" world"CR
var t = BQhelloCR
worldBQ
var u = BQhCReCRlCRlCRoCR
worldBQ
var golden = "hello\n world"
func main() {
if s != golden {
fmt.Printf("s=%q, want %q", s, golden)
}
if t != golden {
fmt.Printf("t=%q, want %q", t, golden)
}
if u != golden {
fmt.Printf("u=%q, want %q", u, golden)
}
}
`
...@@ -15,8 +15,8 @@ var ( ...@@ -15,8 +15,8 @@ var (
_ = sum() _ = sum()
_ = sum(1.0, 2.0) _ = sum(1.0, 2.0)
_ = sum(1.5) // ERROR "integer" _ = sum(1.5) // ERROR "integer"
_ = sum("hello") // ERROR "string.*as type int|incompatible" _ = sum("hello") // ERROR ".hello. .type string. as type int|incompatible"
_ = sum([]int{1}) // ERROR "slice literal.*as type int|incompatible" _ = sum([]int{1}) // ERROR "\[\]int literal.*as type int|incompatible"
) )
type T []T type T []T
......
// $G $D/$F.go && $L $F.$A && ./$A.out // $G $D/$F.go && $L $F.$A && ./$A.out 2>&1 | cmp - $D/$F.out
// 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
......
printing: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
42 true false true +1.500000e+000 world 0x0 [0/0]0x0 0x0 0x0 255
// $G $D/$F.go && $L $F.$A && ./$A.out
// 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.
//line foo/bar.y:4
package main
//line foo/bar.y:60
func main() {
//line foo/bar.y:297
f, l := 0, 0
//line yacctab:1
f, l = 1, 1
//line yaccpar:1
f, l = 2, 1
//line foo/bar.y:82
f, l = 3, 82
//line foo/bar.y:90
f, l = 3, 90
//line foo/bar.y:92
f, l = 3, 92
//line foo/bar.y:100
f, l = 3, 100
//line foo/bar.y:104
l = 104
//line foo/bar.y:112
l = 112
//line foo/bar.y:117
l = 117
//line foo/bar.y:121
l = 121
//line foo/bar.y:125
l = 125
//line foo/bar.y:133
l = 133
//line foo/bar.y:146
l = 146
//line foo/bar.y:148
//line foo/bar.y:153
//line foo/bar.y:155
l = 155
//line foo/bar.y:160
//line foo/bar.y:164
//line foo/bar.y:173
//line foo/bar.y:178
//line foo/bar.y:180
//line foo/bar.y:185
//line foo/bar.y:195
//line foo/bar.y:197
//line foo/bar.y:202
//line foo/bar.y:204
//line foo/bar.y:208
//line foo/bar.y:211
//line foo/bar.y:213
//line foo/bar.y:215
//line foo/bar.y:217
//line foo/bar.y:221
//line foo/bar.y:229
//line foo/bar.y:236
//line foo/bar.y:238
//line foo/bar.y:240
//line foo/bar.y:244
//line foo/bar.y:249
//line foo/bar.y:253
//line foo/bar.y:257
//line foo/bar.y:262
//line foo/bar.y:267
//line foo/bar.y:272
if l == f {
//line foo/bar.y:277
panic("aie!")
//line foo/bar.y:281
}
//line foo/bar.y:285
return
//line foo/bar.y:288
//line foo/bar.y:290
}
//line foo/bar.y:293
//line foo/bar.y:295
// $G $D/$F.go $D/z*.go && $L $F.$A && ./$A.out
// 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
func main() {
F1()
F2()
F3()
F4()
F5()
F6()
F7()
F8()
F9()
F10()
F11()
F12()
F13()
F14()
F15()
F16()
F17()
F18()
F19()
F20()
}
//line x1.go:4
package main
func F1() {}
//line x10.go:4
package main
func F10() {}
//line x11.go:4
package main
func F11() {}
//line x12.go:4
package main
func F12() {}
//line x13.go:4
package main
func F13() {}
//line x14.go:4
package main
func F14() {}
//line x15.go:4
package main
func F15() {}
//line x16.go:4
package main
func F16() {}
//line x17.go:4
package main
func F17() {}
//line x18.go:4
package main
func F18() {}
//line x19.go:4
package main
func F19() {}
//line x2.go:4
package main
func F2() {}
//line x20.go:4
package main
func F20() {}
//line x3.go:4
package main
func F3() {}
//line x4.go:4
package main
func F4() {}
//line x5.go:4
package main
func F5() {}
//line x6.go:4
package main
func F6() {}
//line x7.go:4
package main
func F7() {}
//line x8.go:4
package main
func F8() {}
//line x9.go:4
package main
func F9() {}
// errchk -0 $G -m -l $D/$F.go
// 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.
package foo
import (
"fmt"
"unsafe"
)
var gxx *int
func foo1(x int) { // ERROR "moved to heap: x"
gxx = &x // ERROR "&x escapes to heap"
}
func foo2(yy *int) { // ERROR "leaking param: yy"
gxx = yy
}
func foo3(x int) *int { // ERROR "moved to heap: x"
return &x // ERROR "&x escapes to heap"
}
type T *T
func foo3b(t T) { // ERROR "leaking param: t"
*t = t
}
// xx isn't going anywhere, so use of yy is ok
func foo4(xx, yy *int) { // ERROR "xx does not escape" "yy does not escape"
xx = yy
}
// xx isn't going anywhere, so taking address of yy is ok
func foo5(xx **int, yy *int) { // ERROR "xx does not escape" "yy does not escape"
xx = &yy // ERROR "&yy does not escape"
}
func foo6(xx **int, yy *int) { // ERROR "xx does not escape" "leaking param: yy"
*xx = yy
}
func foo7(xx **int, yy *int) { // ERROR "xx does not escape" "yy does not escape"
**xx = *yy
}
func foo8(xx, yy *int) int { // ERROR "xx does not escape" "yy does not escape"
xx = yy
return *xx
}
func foo9(xx, yy *int) *int { // ERROR "leaking param: xx" "leaking param: yy"
xx = yy
return xx
}
func foo10(xx, yy *int) { // ERROR "xx does not escape" "yy does not escape"
*xx = *yy
}
func foo11() int {
x, y := 0, 42
xx := &x // ERROR "&x does not escape"
yy := &y // ERROR "&y does not escape"
*xx = *yy
return x
}
var xxx **int
func foo12(yyy **int) { // ERROR "leaking param: yyy"
xxx = yyy
}
func foo13(yyy **int) { // ERROR "yyy does not escape"
*xxx = *yyy
}
func foo14(yyy **int) { // ERROR "yyy does not escape"
**xxx = **yyy
}
func foo15(yy *int) { // ERROR "moved to heap: yy"
xxx = &yy // ERROR "&yy escapes to heap"
}
func foo16(yy *int) { // ERROR "leaking param: yy"
*xxx = yy
}
func foo17(yy *int) { // ERROR "yy does not escape"
**xxx = *yy
}
func foo18(y int) { // ERROR "moved to heap: "y"
*xxx = &y // ERROR "&y escapes to heap"
}
func foo19(y int) {
**xxx = y
}
type Bar struct {
i int
ii *int
}
func NewBar() *Bar {
return &Bar{42, nil} // ERROR "&Bar literal escapes to heap"
}
func NewBarp(x *int) *Bar { // ERROR "leaking param: x"
return &Bar{42, x} // ERROR "&Bar literal escapes to heap"
}
func NewBarp2(x *int) *Bar { // ERROR "x does not escape"
return &Bar{*x, nil} // ERROR "&Bar literal escapes to heap"
}
func (b *Bar) NoLeak() int { // ERROR "b does not escape"
return *(b.ii)
}
func (b *Bar) Leak() *int { // ERROR "leaking param: b"
return &b.i // ERROR "&b.i escapes to heap"
}
func (b *Bar) AlsoNoLeak() *int { // ERROR "b does not escape"
return b.ii
}
func (b Bar) AlsoLeak() *int { // ERROR "leaking param: b"
return b.ii
}
func (b Bar) LeaksToo() *int { // ERROR "leaking param: b"
v := 0 // ERROR "moved to heap: v"
b.ii = &v // ERROR "&v escapes"
return b.ii
}
func (b *Bar) LeaksABit() *int { // ERROR "b does not escape"
v := 0 // ERROR "moved to heap: v"
b.ii = &v // ERROR "&v escapes"
return b.ii
}
func (b Bar) StillNoLeak() int { // ERROR "b does not escape"
v := 0
b.ii = &v // ERROR "&v does not escape"
return b.i
}
func goLeak(b *Bar) { // ERROR "leaking param: b"
go b.NoLeak()
}
type Bar2 struct {
i [12]int
ii []int
}
func NewBar2() *Bar2 {
return &Bar2{[12]int{42}, nil} // ERROR "&Bar2 literal escapes to heap"
}
func (b *Bar2) NoLeak() int { // ERROR "b does not escape"
return b.i[0]
}
func (b *Bar2) Leak() []int { // ERROR "leaking param: b"
return b.i[:] // ERROR "b.i escapes to heap"
}
func (b *Bar2) AlsoNoLeak() []int { // ERROR "b does not escape"
return b.ii[0:1]
}
func (b Bar2) AgainNoLeak() [12]int { // ERROR "b does not escape"
return b.i
}
func (b *Bar2) LeakSelf() { // ERROR "leaking param: b"
b.ii = b.i[0:4] // ERROR "b.i escapes to heap"
}
func (b *Bar2) LeakSelf2() { // ERROR "leaking param: b"
var buf []int
buf = b.i[0:] // ERROR "b.i escapes to heap"
b.ii = buf
}
func foo21() func() int {
x := 42 // ERROR "moved to heap: x"
return func() int { // ERROR "func literal escapes to heap"
return x // ERROR "&x escapes to heap"
}
}
func foo22() int {
x := 42
return func() int { // ERROR "func literal does not escape"
return x
}()
}
func foo23(x int) func() int { // ERROR "moved to heap: x"
return func() int { // ERROR "func literal escapes to heap"
return x // ERROR "&x escapes to heap"
}
}
func foo23a(x int) func() int { // ERROR "moved to heap: x"
f := func() int { // ERROR "func literal escapes to heap"
return x // ERROR "&x escapes to heap"
}
return f
}
func foo23b(x int) *(func() int) { // ERROR "moved to heap: x"
f := func() int { return x } // ERROR "moved to heap: f" "func literal escapes to heap" "&x escapes to heap"
return &f // ERROR "&f escapes to heap"
}
func foo24(x int) int {
return func() int { // ERROR "func literal does not escape"
return x
}()
}
var x *int
func fooleak(xx *int) int { // ERROR "leaking param: xx"
x = xx
return *x
}
func foonoleak(xx *int) int { // ERROR "xx does not escape"
return *x + *xx
}
func foo31(x int) int { // ERROR "moved to heap: x"
return fooleak(&x) // ERROR "&x escapes to heap"
}
func foo32(x int) int {
return foonoleak(&x) // ERROR "&x does not escape"
}
type Foo struct {
xx *int
x int
}
var F Foo
var pf *Foo
func (f *Foo) fooleak() { // ERROR "leaking param: f"
pf = f
}
func (f *Foo) foonoleak() { // ERROR "f does not escape"
F.x = f.x
}
func (f *Foo) Leak() { // ERROR "leaking param: f"
f.fooleak()
}
func (f *Foo) NoLeak() { // ERROR "f does not escape"
f.foonoleak()
}
func foo41(x int) { // ERROR "moved to heap: x"
F.xx = &x // ERROR "&x escapes to heap"
}
func (f *Foo) foo42(x int) { // ERROR "f does not escape" "moved to heap: x"
f.xx = &x // ERROR "&x escapes to heap"
}
func foo43(f *Foo, x int) { // ERROR "f does not escape" "moved to heap: x"
f.xx = &x // ERROR "&x escapes to heap"
}
func foo44(yy *int) { // ERROR "leaking param: yy"
F.xx = yy
}
func (f *Foo) foo45() { // ERROR "f does not escape"
F.x = f.x
}
func (f *Foo) foo46() { // ERROR "f does not escape"
F.xx = f.xx
}
func (f *Foo) foo47() { // ERROR "leaking param: f"
f.xx = &f.x // ERROR "&f.x escapes to heap"
}
var ptrSlice []*int
func foo50(i *int) { // ERROR "leaking param: i"
ptrSlice[0] = i
}
var ptrMap map[*int]*int
func foo51(i *int) { // ERROR "leaking param: i"
ptrMap[i] = i
}
func indaddr1(x int) *int { // ERROR "moved to heap: x"
return &x // ERROR "&x escapes to heap"
}
func indaddr2(x *int) *int { // ERROR "leaking param: x"
return *&x // ERROR "&x does not escape"
}
func indaddr3(x *int32) *int { // ERROR "leaking param: x"
return *(**int)(unsafe.Pointer(&x)) // ERROR "&x does not escape"
}
// From package math:
func Float32bits(f float32) uint32 {
return *(*uint32)(unsafe.Pointer(&f)) // ERROR "&f does not escape"
}
func Float32frombits(b uint32) float32 {
return *(*float32)(unsafe.Pointer(&b)) // ERROR "&b does not escape"
}
func Float64bits(f float64) uint64 {
return *(*uint64)(unsafe.Pointer(&f)) // ERROR "&f does not escape"
}
func Float64frombits(b uint64) float64 {
return *(*float64)(unsafe.Pointer(&b)) // ERROR "&b does not escape"
}
// contrast with
func float64bitsptr(f float64) *uint64 { // ERROR "moved to heap: f"
return (*uint64)(unsafe.Pointer(&f)) // ERROR "&f escapes to heap"
}
func float64ptrbitsptr(f *float64) *uint64 { // ERROR "leaking param: f"
return (*uint64)(unsafe.Pointer(f))
}
func typesw(i interface{}) *int { // ERROR "leaking param: i"
switch val := i.(type) {
case *int:
return val
case *int8:
v := int(*val) // ERROR "moved to heap: v"
return &v // ERROR "&v escapes to heap"
}
return nil
}
func exprsw(i *int) *int { // ERROR "leaking param: i"
switch j := i; *j + 110 {
case 12:
return j
case 42:
return nil
}
return nil
}
// assigning to an array element is like assigning to the array
func foo60(i *int) *int { // ERROR "leaking param: i"
var a [12]*int
a[0] = i
return a[1]
}
func foo60a(i *int) *int { // ERROR "i does not escape"
var a [12]*int
a[0] = i
return nil
}
// assigning to a struct field is like assigning to the struct
func foo61(i *int) *int { // ERROR "leaking param: i"
type S struct {
a, b *int
}
var s S
s.a = i
return s.b
}
func foo61a(i *int) *int { // ERROR "i does not escape"
type S struct {
a, b *int
}
var s S
s.a = i
return nil
}
// assigning to a struct field is like assigning to the struct but
// here this subtlety is lost, since s.a counts as an assignment to a
// track-losing dereference.
func foo62(i *int) *int { // ERROR "leaking param: i"
type S struct {
a, b *int
}
s := new(S) // ERROR "new[(]S[)] does not escape"
s.a = i
return nil // s.b
}
type M interface {
M()
}
func foo63(m M) { // ERROR "m does not escape"
}
func foo64(m M) { // ERROR "leaking param: m"
m.M()
}
func foo64b(m M) { // ERROR "leaking param: m"
defer m.M()
}
type MV int
func (MV) M() {}
func foo65() {
var mv MV
foo63(&mv) // ERROR "&mv does not escape"
}
func foo66() {
var mv MV // ERROR "moved to heap: mv"
foo64(&mv) // ERROR "&mv escapes to heap"
}
func foo67() {
var mv MV
foo63(mv)
}
func foo68() {
var mv MV
foo64(mv) // escapes but it's an int so irrelevant
}
func foo69(m M) { // ERROR "leaking param: m"
foo64(m)
}
func foo70(mv1 *MV, m M) { // ERROR "leaking param: mv1" "leaking param: m"
m = mv1
foo64(m)
}
func foo71(x *int) []*int { // ERROR "leaking param: x"
var y []*int
y = append(y, x)
return y
}
func foo71a(x int) []*int { // ERROR "moved to heap: x"
var y []*int
y = append(y, &x) // ERROR "&x escapes to heap"
return y
}
func foo72() {
var x int
var y [1]*int
y[0] = &x // ERROR "&x does not escape"
}
func foo72aa() [10]*int {
var x int // ERROR "moved to heap: x"
var y [10]*int
y[0] = &x // ERROR "&x escapes to heap"
return y
}
func foo72a() {
var y [10]*int
for i := 0; i < 10; i++ {
// escapes its scope
x := i // ERROR "moved to heap: x"
y[i] = &x // ERROR "&x escapes to heap"
}
return
}
func foo72b() [10]*int {
var y [10]*int
for i := 0; i < 10; i++ {
x := i // ERROR "moved to heap: x"
y[i] = &x // ERROR "&x escapes to heap"
}
return y
}
// issue 2145
func foo73() {
s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
for _, v := range s {
vv := v // ERROR "moved to heap: vv"
// actually just escapes its scope
defer func() { // ERROR "func literal escapes to heap"
println(vv) // ERROR "&vv escapes to heap"
}()
}
}
func foo74() {
s := []int{3, 2, 1} // ERROR "\[\]int literal does not escape"
for _, v := range s {
vv := v // ERROR "moved to heap: vv"
// actually just escapes its scope
fn := func() { // ERROR "func literal escapes to heap"
println(vv) // ERROR "&vv escapes to heap"
}
defer fn()
}
}
func myprint(y *int, x ...interface{}) *int { // ERROR "x does not escape" "leaking param: y"
return y
}
func myprint1(y *int, x ...interface{}) *interface{} { // ERROR "y does not escape" "leaking param: x"
return &x[0] // ERROR "&x.0. escapes to heap"
}
func foo75(z *int) { // ERROR "leaking param: z"
myprint(z, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
}
func foo75a(z *int) { // ERROR "z does not escape"
myprint1(z, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
}
func foo76(z *int) { // ERROR "leaking param: z"
myprint(nil, z) // ERROR "[.][.][.] argument does not escape"
}
func foo76a(z *int) { // ERROR "leaking param: z"
myprint1(nil, z) // ERROR "[.][.][.] argument escapes to heap"
}
func foo76b() {
myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
}
func foo76c() {
myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
}
func foo76d() {
defer myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument does not escape"
}
func foo76e() {
defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
}
func foo76f() {
for {
// TODO: This one really only escapes its scope, but we don't distinguish yet.
defer myprint(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
}
}
func foo76g() {
for {
defer myprint1(nil, 1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
}
}
func foo77(z []interface{}) { // ERROR "z does not escape"
myprint(nil, z...) // z does not escape
}
func foo77a(z []interface{}) { // ERROR "leaking param: z"
myprint1(nil, z...)
}
func foo78(z int) *int { // ERROR "moved to heap: z"
return &z // ERROR "&z escapes to heap"
}
func foo78a(z int) *int { // ERROR "moved to heap: z"
y := &z // ERROR "&z escapes to heap"
x := &y // ERROR "&y does not escape"
return *x // really return y
}
func foo79() *int {
return new(int) // ERROR "new[(]int[)] escapes to heap"
}
func foo80() *int {
var z *int
for {
// Really just escapes its scope but we don't distinguish
z = new(int) // ERROR "new[(]int[)] escapes to heap"
}
_ = z
return nil
}
func foo81() *int {
for {
z := new(int) // ERROR "new[(]int[)] does not escape"
_ = z
}
return nil
}
type Fooer interface {
Foo()
}
type LimitedFooer struct {
Fooer
N int64
}
func LimitFooer(r Fooer, n int64) Fooer { // ERROR "leaking param: r"
return &LimitedFooer{r, n} // ERROR "&LimitedFooer literal escapes to heap"
}
func foo90(x *int) map[*int]*int { // ERROR "leaking param: x"
return map[*int]*int{nil: x} // ERROR "map\[\*int\]\*int literal escapes to heap"
}
func foo91(x *int) map[*int]*int { // ERROR "leaking param: x"
return map[*int]*int{x: nil} // ERROR "map\[\*int\]\*int literal escapes to heap"
}
func foo92(x *int) [2]*int { // ERROR "leaking param: x"
return [2]*int{x, nil}
}
// does not leak c
func foo93(c chan *int) *int { // ERROR "c does not escape"
for v := range c {
return v
}
return nil
}
// does not leak m
func foo94(m map[*int]*int, b bool) *int { // ERROR "m does not escape"
for k, v := range m {
if b {
return k
}
return v
}
return nil
}
// does leak x
func foo95(m map[*int]*int, x *int) { // ERROR "m does not escape" "leaking param: x"
m[x] = x
}
// does not leak m
func foo96(m []*int) *int { // ERROR "m does not escape"
return m[0]
}
// does leak m
func foo97(m [1]*int) *int { // ERROR "leaking param: m"
return m[0]
}
// does not leak m
func foo98(m map[int]*int) *int { // ERROR "m does not escape"
return m[0]
}
// does leak m
func foo99(m *[1]*int) []*int { // ERROR "leaking param: m"
return m[:]
}
// does not leak m
func foo100(m []*int) *int { // ERROR "m does not escape"
for _, v := range m {
return v
}
return nil
}
// does leak m
func foo101(m [1]*int) *int { // ERROR "leaking param: m"
for _, v := range m {
return v
}
return nil
}
// does not leak m
func foo101a(m [1]*int) *int { // ERROR "m does not escape"
for i := range m { // ERROR "moved to heap: i"
return &i // ERROR "&i escapes to heap"
}
return nil
}
// does leak x
func foo102(m []*int, x *int) { // ERROR "m does not escape" "leaking param: x"
m[0] = x
}
// does not leak x
func foo103(m [1]*int, x *int) { // ERROR "m does not escape" "x does not escape"
m[0] = x
}
var y []*int
// does not leak x
func foo104(x []*int) { // ERROR "x does not escape"
copy(y, x)
}
// does not leak x
func foo105(x []*int) { // ERROR "x does not escape"
_ = append(y, x...)
}
// does leak x
func foo106(x *int) { // ERROR "leaking param: x"
_ = append(y, x)
}
func foo107(x *int) map[*int]*int { // ERROR "leaking param: x"
return map[*int]*int{x: nil} // ERROR "map.* literal escapes to heap"
}
func foo108(x *int) map[*int]*int { // ERROR "leaking param: x"
return map[*int]*int{nil: x} // ERROR "map.* literal escapes to heap"
}
func foo109(x *int) *int { // ERROR "leaking param: x"
m := map[*int]*int{x: nil} // ERROR "map.* literal does not escape"
for k, _ := range m {
return k
}
return nil
}
func foo110(x *int) *int { // ERROR "leaking param: x"
m := map[*int]*int{nil: x} // ERROR "map.* literal does not escape"
return m[nil]
}
func foo111(x *int) *int { // ERROR "leaking param: x"
m := []*int{x} // ERROR "\[\]\*int literal does not escape"
return m[0]
}
func foo112(x *int) *int { // ERROR "leaking param: x"
m := [1]*int{x}
return m[0]
}
func foo113(x *int) *int { // ERROR "leaking param: x"
m := Bar{ii: x}
return m.ii
}
func foo114(x *int) *int { // ERROR "leaking param: x"
m := &Bar{ii: x} // ERROR "&Bar literal does not escape"
return m.ii
}
func foo115(x *int) *int { // ERROR "leaking param: x"
return (*int)(unsafe.Pointer(uintptr(unsafe.Pointer(x)) + 1))
}
func foo116(b bool) *int {
if b {
x := 1 // ERROR "moved to heap: x"
return &x // ERROR "&x escapes to heap"
} else {
y := 1 // ERROR "moved to heap: y"
return &y // ERROR "&y escapes to heap"
}
return nil
}
func foo117(unknown func(interface{})) { // ERROR "unknown does not escape"
x := 1 // ERROR "moved to heap: x"
unknown(&x) // ERROR "&x escapes to heap"
}
func foo118(unknown func(*int)) { // ERROR "unknown does not escape"
x := 1 // ERROR "moved to heap: x"
unknown(&x) // ERROR "&x escapes to heap"
}
func external(*int)
func foo119(x *int) { // ERROR "leaking param: x"
external(x)
}
func foo120() {
// formerly exponential time analysis
L1:
L2:
L3:
L4:
L5:
L6:
L7:
L8:
L9:
L10:
L11:
L12:
L13:
L14:
L15:
L16:
L17:
L18:
L19:
L20:
L21:
L22:
L23:
L24:
L25:
L26:
L27:
L28:
L29:
L30:
L31:
L32:
L33:
L34:
L35:
L36:
L37:
L38:
L39:
L40:
L41:
L42:
L43:
L44:
L45:
L46:
L47:
L48:
L49:
L50:
L51:
L52:
L53:
L54:
L55:
L56:
L57:
L58:
L59:
L60:
L61:
L62:
L63:
L64:
L65:
L66:
L67:
L68:
L69:
L70:
L71:
L72:
L73:
L74:
L75:
L76:
L77:
L78:
L79:
L80:
L81:
L82:
L83:
L84:
L85:
L86:
L87:
L88:
L89:
L90:
L91:
L92:
L93:
L94:
L95:
L96:
L97:
L98:
L99:
L100:
// use the labels to silence compiler errors
goto L1
goto L2
goto L3
goto L4
goto L5
goto L6
goto L7
goto L8
goto L9
goto L10
goto L11
goto L12
goto L13
goto L14
goto L15
goto L16
goto L17
goto L18
goto L19
goto L20
goto L21
goto L22
goto L23
goto L24
goto L25
goto L26
goto L27
goto L28
goto L29
goto L30
goto L31
goto L32
goto L33
goto L34
goto L35
goto L36
goto L37
goto L38
goto L39
goto L40
goto L41
goto L42
goto L43
goto L44
goto L45
goto L46
goto L47
goto L48
goto L49
goto L50
goto L51
goto L52
goto L53
goto L54
goto L55
goto L56
goto L57
goto L58
goto L59
goto L60
goto L61
goto L62
goto L63
goto L64
goto L65
goto L66
goto L67
goto L68
goto L69
goto L70
goto L71
goto L72
goto L73
goto L74
goto L75
goto L76
goto L77
goto L78
goto L79
goto L80
goto L81
goto L82
goto L83
goto L84
goto L85
goto L86
goto L87
goto L88
goto L89
goto L90
goto L91
goto L92
goto L93
goto L94
goto L95
goto L96
goto L97
goto L98
goto L99
goto L100
}
func foo121() {
for i := 0; i < 10; i++ {
defer myprint(nil, i) // ERROR "[.][.][.] argument escapes to heap"
go myprint(nil, i) // ERROR "[.][.][.] argument escapes to heap"
}
}
// same as foo121 but check across import
func foo121b() {
for i := 0; i < 10; i++ {
defer fmt.Printf("%d", i) // ERROR "[.][.][.] argument escapes to heap"
go fmt.Printf("%d", i) // ERROR "[.][.][.] argument escapes to heap"
}
}
// a harmless forward jump
func foo122() {
var i *int
goto L1
L1:
i = new(int) // ERROR "does not escape"
_ = i
}
// a backward jump, increases loopdepth
func foo123() {
var i *int
L1:
i = new(int) // ERROR "escapes"
goto L1
_ = i
}
// $G $D/$F.go && $L $F.$A && ./$A.out
// 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 run-time behavior of escape analysis-related optimizations.
package main
func main() {
test1()
}
func test1() {
check1(0)
check1(1)
check1(2)
}
type T1 struct {
X, Y, Z int
}
func f() int {
return 1
}
func check1(pass int) T1 {
v := []T1{{X: f(), Z: f()}}
if v[0].Y != 0 {
panic("nonzero init")
}
v[0].Y = pass
return v[0]
}
...@@ -6,53 +6,76 @@ ...@@ -6,53 +6,76 @@
package main package main
import "fmt"
type Element interface { type Element interface {
} }
type Vector struct { type Vector struct {
nelem int; nelem int
elem []Element; elem []Element
} }
func New() *Vector { func New() *Vector {
v := new(Vector); v := new(Vector)
v.nelem = 0; v.nelem = 0
v.elem = make([]Element, 10); v.elem = make([]Element, 10)
return v; return v
} }
func (v *Vector) At(i int) Element { func (v *Vector) At(i int) Element {
return v.elem[i]; return v.elem[i]
} }
func (v *Vector) Insert(e Element) { func (v *Vector) Insert(e Element) {
v.elem[v.nelem] = e; v.elem[v.nelem] = e
v.nelem++; v.nelem++
} }
func main() { func main() {
type I struct { val int; }; type I struct{ val int }
i0 := new(I); i0.val = 0; i0 := new(I)
i1 := new(I); i1.val = 11; i0.val = 0
i2 := new(I); i2.val = 222; i1 := new(I)
i3 := new(I); i3.val = 3333; i1.val = 11
i4 := new(I); i4.val = 44444; i2 := new(I)
v := New(); i2.val = 222
print("hi\n"); i3 := new(I)
v.Insert(i4); i3.val = 3333
v.Insert(i3); i4 := new(I)
v.Insert(i2); i4.val = 44444
v.Insert(i1); v := New()
v.Insert(i0); r := "hi\n"
v.Insert(i4)
v.Insert(i3)
v.Insert(i2)
v.Insert(i1)
v.Insert(i0)
for i := 0; i < v.nelem; i++ { for i := 0; i < v.nelem; i++ {
var x *I; var x *I
x = v.At(i).(*I); x = v.At(i).(*I)
print(i, " ", x.val, "\n"); // prints correct list r += fmt.Sprintln(i, x.val) // prints correct list
} }
for i := 0; i < v.nelem; i++ { for i := 0; i < v.nelem; i++ {
print(i, " ", v.At(i).(*I).val, "\n"); r += fmt.Sprintln(i, v.At(i).(*I).val)
}
expect := `hi
0 44444
1 3333
2 222
3 11
4 0
0 44444
1 3333
2 222
3 11
4 0
`
if r != expect {
panic(r)
} }
} }
/* /*
bug027.go:50: illegal types for operand bug027.go:50: illegal types for operand
(<Element>I{}) CONV (<I>{}) (<Element>I{}) CONV (<I>{})
......
...@@ -10,6 +10,6 @@ var c chan int ...@@ -10,6 +10,6 @@ var c chan int
func main() { func main() {
c = make(chan int); c = make(chan int);
go func() { print("ok\n"); c <- 0 } (); go func() { c <- 0 } ();
<-c <-c
} }
...@@ -6,20 +6,35 @@ ...@@ -6,20 +6,35 @@
package main package main
import "fmt"
func main() { func main() {
var i, k int; var i, k int
outer: var r string
for k=0; k<2; k++ { outer:
print("outer loop top k ", k, "\n"); for k = 0; k < 2; k++ {
if k != 0 { panic("k not zero") } // inner loop breaks this one every time r += fmt.Sprintln("outer loop top k", k)
for i=0; i<2; i++ { if k != 0 {
if i != 0 { panic("i not zero") } // loop breaks every time panic("k not zero")
print("inner loop top i ", i, "\n"); } // inner loop breaks this one every time
for i = 0; i < 2; i++ {
if i != 0 {
panic("i not zero")
} // loop breaks every time
r += fmt.Sprintln("inner loop top i", i)
if true { if true {
print("do break\n"); r += "do break\n"
break outer; break outer
} }
} }
} }
print("broke\n"); r += "broke\n"
expect := `outer loop top k 0
inner loop top i 0
do break
broke
`
if r != expect {
panic(r)
}
} }
...@@ -10,7 +10,6 @@ type S struct { ...@@ -10,7 +10,6 @@ type S struct {
} }
func (p *S) M() { func (p *S) M() {
print("M\n");
} }
type I interface { type I interface {
......
// $G $D/$F.go && $L $F.$A && (! ./$A.out || echo BUG: should not succeed) // $G $D/$F.go && $L $F.$A && ./$A.out
// 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
...@@ -21,8 +21,24 @@ func main() { ...@@ -21,8 +21,24 @@ func main() {
if foo2(v2) != 1 { if foo2(v2) != 1 {
panic(2) panic(2)
} }
shouldPanic(p1)
}
func p1() {
var i I
i = 1
var v3 = i.(int32) // This type conversion should fail at runtime. var v3 = i.(int32) // This type conversion should fail at runtime.
if foo2(v3) != 1 { if foo2(v3) != 1 {
panic(3) panic(3)
} }
} }
func shouldPanic(f func()) {
defer func() {
if recover() == nil {
panic("function should panic")
}
}()
f()
}
// $G $D/$F.go && $L $F.$A && ! ./$A.out || echo BUG: should crash // $G $D/$F.go && $L $F.$A && ./$A.out
// 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
...@@ -8,6 +8,8 @@ package main ...@@ -8,6 +8,8 @@ package main
type T struct {a, b int}; type T struct {a, b int};
func println(x, y int) { }
func f(x interface{}) interface{} { func f(x interface{}) interface{} {
type T struct {a, b int}; type T struct {a, b int};
...@@ -24,16 +26,29 @@ func main() { ...@@ -24,16 +26,29 @@ func main() {
inner_T := f(nil); inner_T := f(nil);
f(inner_T); f(inner_T);
shouldPanic(p1)
}
func p1() {
outer_T := T{5, 7}; outer_T := T{5, 7};
f(outer_T); f(outer_T);
} }
func shouldPanic(f func()) {
defer func() {
if recover() == nil {
panic("function should panic")
}
}()
f()
}
/* /*
This prints: This prints:
2 3 2 3
5 7 5 7
but it should crash: The type assertion on line 14 should fail but it should crash: The type assertion on line 18 should fail
for the 2nd call to f with outer_T. for the 2nd call to f with outer_T.
*/ */
...@@ -93,7 +93,8 @@ func main() { ...@@ -93,7 +93,8 @@ func main() {
m[13] = 'B' m[13] = 'B'
// 13 14 // 13 14
m[gint()] = gbyte(), false delete(m, gint())
gbyte()
if _, present := m[13]; present { if _, present := m[13]; present {
println("bad map removal") println("bad map removal")
panic("fail") panic("fail")
......
// $G $D/$F.go
// 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.
// http://code.google.com/p/go/issues/detail?id=746
package main
type I interface { F() }
type T struct{}
func (T) F() {}
func main() {
switch I(T{}).(type) {
case interface{}:
}
}
...@@ -12,16 +12,14 @@ type I interface { ...@@ -12,16 +12,14 @@ type I interface {
f() f()
} }
var callee string var callee string
var error bool var error_ bool
type T int type T int
func (t *T) f() { callee = "f" } func (t *T) f() { callee = "f" }
func (i *T) g() { callee = "g" } func (i *T) g() { callee = "g" }
// test1 and test2 are the same except that in the interface J // test1 and test2 are the same except that in the interface J
// the entries are swapped. test2 and test3 are the same except // the entries are swapped. test2 and test3 are the same except
// that in test3 the interface J is declared outside the function. // that in test3 the interface J is declared outside the function.
...@@ -36,11 +34,10 @@ func test1(x I) { ...@@ -36,11 +34,10 @@ func test1(x I) {
x.(J).f() x.(J).f()
if callee != "f" { if callee != "f" {
println("test1 called", callee) println("test1 called", callee)
error = true error_ = true
} }
} }
func test2(x I) { func test2(x I) {
type J interface { type J interface {
g() g()
...@@ -49,11 +46,10 @@ func test2(x I) { ...@@ -49,11 +46,10 @@ func test2(x I) {
x.(J).f() x.(J).f()
if callee != "f" { if callee != "f" {
println("test2 called", callee) println("test2 called", callee)
error = true error_ = true
} }
} }
type J interface { type J interface {
g() g()
I I
...@@ -63,7 +59,7 @@ func test3(x I) { ...@@ -63,7 +59,7 @@ func test3(x I) {
x.(J).f() x.(J).f()
if callee != "f" { if callee != "f" {
println("test3 called", callee) println("test3 called", callee)
error = true error_ = true
} }
} }
...@@ -72,7 +68,7 @@ func main() { ...@@ -72,7 +68,7 @@ func main() {
test1(x) test1(x)
test2(x) test2(x)
test3(x) test3(x)
if error { if error_ {
panic("wrong method called") panic("wrong method called")
} }
} }
......
// $G $D/$F.go && $L $F.$A && ./$A.out // $G $D/$F.go && $L $F.$A && ./$A.out 2>&1 | cmp - $D/$F.out
// 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,8 +10,8 @@ package main ...@@ -10,8 +10,8 @@ package main
func main() { func main() {
var x interface{} var x interface{}
switch t := x.(type) { // GC_ERROR "0 is not a type" switch t := x.(type) {
case 0: // GCCGO_ERROR "expected type" case 0: // ERROR "type"
t.x = 1 // ERROR "type interface \{ \}|reference to undefined field or method" t.x = 1 // ERROR "type interface \{\}|reference to undefined field or method"
} }
} }
...@@ -12,11 +12,11 @@ ...@@ -12,11 +12,11 @@
package main package main
type S struct { type S struct {
err os.Error // ERROR "undefined|expected package" err foo.Bar // ERROR "undefined|expected package"
Num int Num int
} }
func main() { func main() {
s := S{} s := S{}
_ = s.Num // no error here please _ = s.Num // no error here please
} }
// $G $D/$F.go && $L $F.$A && ./$A.out
// 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 2206. Incorrect sign extension of div arguments.
package main
func five(x int64) {
if x != 5 {
panic(x)
}
}
func main() {
// 5
five(int64(5 / (5 / 3)))
// 5
five(int64(byte(5) / (byte(5) / byte(3))))
// 5
var a, b byte = 5, 3
five(int64(a / (a / b)))
// integer divide by zero in golang.org sandbox
// 0 on windows/amd64
x := [3]byte{2, 3, 5}
five(int64(x[2] / (x[2] / x[1])))
// integer divide by zero in golang.org sandbox
// crash on windows/amd64
y := x[1:3]
five(int64(y[1] / (y[1] / y[0])))
}
\ No newline at end of file
package main
import (
"./p"
)
type T struct{ *p.S }
type I interface {
get()
}
func main() {
var t T
p.F(t)
var x interface{} = t
_, ok := x.(I)
if ok {
panic("should not satisfy main.I")
}
_, ok = x.(p.I)
if !ok {
panic("should satisfy p.I")
}
}
package p
type T struct{ x int }
type S struct{}
func (p *S) get() {
}
type I interface {
get()
}
func F(i I) {
i.get()
}
// $G $D/$F.dir/p.go && $G $D/$F.dir/main.go && $L main.$A && ./$A.out || echo BUG: should not fail
// 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.
package ignored
// $G $D/$F.go && $L $F.$A && ./$A.out
// 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.
package main
// 5g bug used to set up the 0 for -f() before calling f,
// and the call to f smashed the register.
func f(n int) int {
s := 0
for i := 0; i < n; i++ {
s += i>>1
}
return s
}
func main() {
x := -f(100)
if x != -2450 {
println(x)
panic("broken")
}
}
// 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.
package pkg
func NonASCII(b []byte, i int) int {
for i = 0; i < len(b); i++ {
if b[i] >= 0x80 {
break
}
}
return i
}
// $G -N -o slow.$A $D/bug369.dir/pkg.go &&
// $G -o fast.$A $D/bug369.dir/pkg.go &&
// $G $D/$F.go && $L $F.$A && ./$A.out
// 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 compiling with optimization turned on produces faster code.
package main
import (
"flag"
"os"
"runtime"
"testing"
fast "./fast"
slow "./slow"
)
var buf = make([]byte, 1048576)
func BenchmarkFastNonASCII(b *testing.B) {
for i := 0; i < b.N; i++ {
fast.NonASCII(buf, 0)
}
}
func BenchmarkSlowNonASCII(b *testing.B) {
for i := 0; i < b.N; i++ {
slow.NonASCII(buf, 0)
}
}
func main() {
os.Args = []string{os.Args[0], "-test.benchtime=0.1"}
flag.Parse()
rslow := testing.Benchmark(BenchmarkSlowNonASCII)
rfast := testing.Benchmark(BenchmarkFastNonASCII)
tslow := rslow.NsPerOp()
tfast := rfast.NsPerOp()
// Optimization should be good for at least 2x, but be forgiving.
// On the ARM simulator we see closer to 1.5x.
speedup := float64(tslow)/float64(tfast)
want := 1.8
if runtime.GOARCH == "arm" {
want = 1.3
}
if speedup < want {
// TODO(rsc): doesn't work on linux-amd64 or darwin-amd64 builders, nor on
// a Lenovo x200 (linux-amd64) laptop.
//println("fast:", tfast, "slow:", tslow, "speedup:", speedup, "want:", want)
//println("not fast enough")
}
}
// $G $D/$F.go && $L $F.$A && ./$A.out
// 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.
package main
// issue 2337
// The program deadlocked.
import "runtime"
func main() {
runtime.GOMAXPROCS(2)
runtime.GC()
runtime.GOMAXPROCS(1)
}
// errchk $G $D/$F.go
// 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 2343
package main
type T struct {}
func (t *T) pm() {}
func (t T) m() {}
func main() {
p := &T{}
p.pm()
p.m()
q := &p
q.m() // ERROR "requires explicit dereference"
q.pm()
}
// $G $D/$F.go && $L $F.$A && ./$A.out || echo BUG: bug372
// 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 2355
package main
type T struct {}
func (T) m() string { return "T" }
type TT struct {
T
m func() string
}
func ff() string { return "ff" }
func main() {
var tt TT
tt.m = ff
if tt.m() != "ff" {
println(tt.m(), "!= \"ff\"")
}
}
// errchk $G $D/$F.go
// 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 873, 2162
package foo
func f(x interface{}) {
switch t := x.(type) { // ERROR "declared and not used"
case int:
}
}
func g(x interface{}) {
switch t := x.(type) {
case int:
case float32:
println(t)
}
}
func h(x interface{}) {
switch t := x.(type) {
case int:
case float32:
default:
println(t)
}
}
// errchk $G $D/$F.go
// 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 1556
package foo
type I interface {
m() int
}
type T int
var _ I = T(0) // GCCGO_ERROR "incompatible"
func (T) m(buf []byte) (a int, b xxxx) { // ERROR "xxxx"
return 0, nil
}
// $G $D/$F.go && $L $F.$A && ./$A.out || echo BUG: bug375
// 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 2423
package main
func main() {
var x interface{} = "hello"
switch x {
case "hello":
default:
println("FAIL")
}
}
// errchk $G $D/$F.go
// 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 1951
package foo
import "unsafe"
var v = unsafe.Sizeof // ERROR "must be called"
package one
func Foo() (n int64, _ *int) {
return 42, nil
}
// $G $D/$F.dir/one.go && $G $D/$F.dir/two.go
// 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 1802
package ignored
// $G $D/$F.go && $L $F.$A && ./$A.out || echo BUG: bug378
// 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 2497
package main
type Header struct{}
func (h Header) Method() {}
var _ interface{} = Header{}
func main() {
type X Header
var _ interface{} = X{}
}
// errchk $G $D/$F.go
// 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 2452.
// Check that the error messages says
// bug378.go:17: 1 + 2 not used
// and not
// bug378.go:17: 1 not used
package main
func main() {
1 + 2 // ERROR "1 \+ 2 not used|value computed is not used"
}
// $G $D/$F.go
// 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.
// Used to cause a typechecking loop error.
package pkg
type T map[int]string
var q = &T{}
// errchk $G $D/$F.go
// 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 2276.
// Check that the error messages says
// bug378.go:19: unsafe.Alignof(0) not used
// and not
// bug378.go:19: 4 not used
package main
import "unsafe"
func main() {
unsafe.Alignof(0) // ERROR "unsafe\.Alignof|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.
package pkg
type T struct {}
var E T
// $G $D/$F.dir/pkg.go && $G $D/$F.go || echo "Bug 382"
// Issue 2529
package main
import "./pkg"
var x = pkg.E
var fo = struct {F pkg.T}{F: x}
// $G $D/$F.go || echo BUG: bug220 // errchk $G $D/$F.go
// Copyright 2009 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.
package main // Issue 2520
package main
func main() { func main() {
m := make(map[int]map[uint]float64) if 2e9 { } // ERROR "2e.09|expected bool"
if 3.14+1i { } // ERROR "3.14 . 1i|expected bool"
m[0] = make(map[uint]float64), false // 6g used to reject this
m[1] = nil
} }
// errchk $G $D/$F.go
// 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 2500
package foo
// Check that we only get root cause message, no further complaints about r undefined
func (r *indexWriter) foo() {} // ERROR "undefined.*indexWriter"
// [ $O == 6 ] || errchk $G -e $D/$F.go
// 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 2444
package main
func main() {
var arr [1000200030]int // ERROR "type .* too large"
arr_bkup := arr
_ = arr_bkup
}
\ No newline at end of file
// [ $O != 6 ] || errchk $G -e $D/$F.go
// 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 2444
package main
func main() { // ERROR "stack frame too large"
var arr [1000200030]int
arr_bkup := arr
_ = arr_bkup
}
// errchk $G $D/$F.go
// 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 2451, 2452
package foo
func f() error { return 0 } // ERROR "cannot use 0 .type int.|has no methods"
func g() error { return -1 } // ERROR "cannot use -1 .type int.|has no methods"
// $G $D/$F.go || echo "Bug387"
// 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 2549
/* Used to die with
missing typecheck: [7f5bf07b4438]
. AS l(45)
. . NAME-main.autotmp_0017 u(1) a(1) l(45) x(0+0) class(PAUTO)
esc(N) tc(1) used(1) ARRAY-[2]string
internal compiler error: missing typecheck
*/
package main
import (
"fmt"
"path/filepath"
)
func main() {
switch _, err := filepath.Glob(filepath.Join(".", "vnc")); {
case err != nil:
fmt.Println(err)
}
}
// errchk $G $D/$F.go
// 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 2231
package main
import "runtime"
func foo(runtime.UintType, i int) { // ERROR "cannot declare name runtime.UintType|named/anonymous mix"
println(i, runtime.UintType)
}
func bar(i int) {
runtime.UintType := i // ERROR "cannot declare name runtime.UintType|non-name on left side"
println(runtime.UintType) // GCCGO_ERROR "invalid use of type"
}
func baz() {
main.i := 1 // ERROR "non-name main.i|non-name on left side"
println(main.i) // GCCGO_ERROR "no fields or methods"
}
func qux() {
var main.i // ERROR "unexpected [.]|expected type"
println(main.i)
}
func corge() {
var foo.i int // ERROR "unexpected [.]|expected type"
println(foo.i)
}
func main() {
foo(42,43)
bar(1969)
}
// errchk $G $D/$F.go
// 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 2563
package foo
func fn(a float32) {}
var f func(arg int) = fn // ERROR "cannot use fn .type func.float32.. as type func.int. in assignment|different parameter types"
// errchk $G -e $D/$F.go
// 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 2627 -- unsafe.Pointer type isn't handled nicely in some errors
package main
import "unsafe"
func main() {
var x *int
_ = unsafe.Pointer(x) - unsafe.Pointer(x) // ERROR "operator - not defined on unsafe.Pointer|expected integer, floating, or complex type"
}
// $G $D/$F.go || echo "Issue2576"
// 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 2576
package bug
type T struct { a int }
func f(t T) {
switch _, _ = t.a, t.a; {}
}
\ No newline at end of file
// 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.
// Functions that the inliner exported incorrectly.
package one
type T int
// Issue 2678
func F1(T *T) bool { return T == nil }
// Issue 2682.
func F2(c chan int) bool { return c == (<-chan int)(nil) }
// Use of single named return value.
func F3() (ret []int) { return append(ret, 1) }
// Call of inlined method with blank receiver.
func (_ *T) M() int { return 1 }
func (t *T) MM() int { return t.M() }
// 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.
// Use the functions in one.go so that the inlined
// forms get type-checked.
package two
import "./one"
func use() {
one.F1(nil)
one.F2(nil)
one.F3()
var t *one.T
t.M()
t.MM()
}
// $G $D/$F.dir/one.go && $G $D/$F.dir/two.go
// 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.
package ignored
// $G $D/$F.go || echo BUG: bug393
// 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 2672
// was trying binary search with an interface type
package main
func f(x interface{}) int {
switch x {
case 1:
return 1
case 2:
return 2
case 3:
return 3
case 4:
return 4
case "5":
return 5
case "6":
return 6
default:
return 7
}
panic("switch")
}
// errchk $G $D/$F.go
// 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 2598
package foo
return nil // ERROR "non-declaration statement outside function body|expected declaration"
// 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 one
type T struct { int }
func New(i int) T { return T{i} }
// 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.
// Use the functions in one.go so that the inlined
// forms get type-checked.
package two
import "./one"
func use() {
_ = one.New(1)
}
\ No newline at end of file
// $G $D/$F.dir/one.go && $G $D/$F.dir/two.go
// 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.
package ignored
// errchk $G -e $D/$F.go
// 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.
package main
// Issue 2623
var m = map[string]int {
"abc":1,
1:2, // ERROR "cannot use 1.*as type string in map key|incompatible type"
}
== ./ == ./
=========== ./cmp2.go
panic: runtime error: comparing uncomparable type []int
=========== ./cmp3.go
panic: runtime error: comparing uncomparable type []int
=========== ./cmp4.go
panic: runtime error: hash of unhashable type []int
=========== ./cmp5.go
panic: runtime error: hash of unhashable type []int
=========== ./deferprint.go
printing: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
42 true false true +1.500000e+000 world 0x0 [0/0]0x0 0x0 0x0 255
=========== ./goprint.go
42 true false true +1.500000e+000 world 0x0 [0/0]0x0 0x0 0x0 255
=========== ./helloworld.go
hello, world
=========== ./peano.go
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880
=========== ./printbig.go
-9223372036854775808
9223372036854775807
=========== ./sigchld.go
survived SIGCHLD
=========== ./sinit.go
FAIL
=========== ./turing.go
Hello World!
== ken/ == ken/
=========== ken/cplx0.go
(+5.000000e+000+6.000000e+000i)
(+5.000000e+000+6.000000e+000i)
(+5.000000e+000+6.000000e+000i)
(+5.000000e+000+6.000000e+000i)
=========== ken/cplx3.go
(+1.292308e+000-1.384615e-001i)
(+1.292308e+000-1.384615e-001i)
=========== ken/cplx4.go
c = (-5.000000-6.000000i)
c = (5.000000+6.000000i)
c = (5.000000+6.000000i)
c = (5.000000+6.000000i)
c = (5+6i)
c = (13+7i)
=========== ken/cplx5.go
(+5.000000e+000-5.000000e+000i)
(+5.000000e+000-5.000000e+000i)
(+5.000000e+000-5.000000e+000i)
(+5.000000e+000-5.000000e+000i)
(+5.000000e+000-5.000000e+000i)
(+5.000000e+000-5.000000e+000i)
(+5.000000e+000-5.000000e+000i)
=========== ken/intervar.go
print 1 bio 2 file 3 -- abc
=========== ken/label.go
100
=========== ken/rob1.go
9876543210
=========== ken/rob2.go
(defn foo (add 12 34))
=========== ken/simpprint.go
hello world
=========== ken/simpswitch.go
0out01out12out2aout34out4fiveout56out6aout78out89out9
=========== ken/string.go
abcxyz-abcxyz-abcxyz-abcxyz-abcxyz-abcxyz-abcxyz
== chan/ == chan/
=========== chan/doubleselect.go
PASS
=========== chan/nonblock.go
PASS
== interface/ == interface/
=========== interface/fail.go
panic: interface conversion: *main.S is not main.I: missing method Foo
=========== interface/returntype.go
panic: interface conversion: *main.S is not main.I2: missing method Name
== nilptr/
== syntax/ == syntax/
== fixedbugs/ == dwarf/
=========== fixedbugs/bug027.go
hi
0 44444
1 3333
2 222
3 11
4 0
0 44444
1 3333
2 222
3 11
4 0
=========== fixedbugs/bug067.go
ok
=========== fixedbugs/bug070.go
outer loop top k 0
inner loop top i 0
do break
broke
=========== fixedbugs/bug093.go
M
=========== fixedbugs/bug113.go
panic: interface conversion: interface is int, not int32
== fixedbugs/
=========== fixedbugs/bug148.go
2 3
panic: interface conversion: interface is main.T, not main.T
=========== fixedbugs/bug328.go
0x0
== bugs/ == bugs/
=========== bugs/bug395.go
bug395 is broken
// $G $D/$F.go && $L $F.$A && ./$A.out // $G $D/$F.go && $L $F.$A && ./$A.out 2>&1 | cmp - $D/$F.out
// 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
......
42 true false true +1.500000e+000 world 0x0 [0/0]0x0 0x0 0x0 255
// $G $F.go && $L $F.$A && ./$A.out // $G $F.go && $L $F.$A && ./$A.out 2>&1 | cmp - $D/$F.out
// 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
......
// $G $D/$F.go && $L $F.$A && ./$A.out
// 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 goroutines and garbage collection run during init.
package main
import "runtime"
var x []byte
func init() {
c := make(chan int)
go send(c)
<-c
const chunk = 1<<20
runtime.UpdateMemStats()
sys := runtime.MemStats.Sys
b := make([]byte, chunk)
for i := range b {
b[i] = byte(i%10 + '0')
}
s := string(b)
for i := 0; i < 1000; i++ {
x = []byte(s)
}
runtime.UpdateMemStats()
sys1 := runtime.MemStats.Sys
if sys1-sys > chunk*50 {
println("allocated 1000 chunks of", chunk, "and used ", sys1-sys, "memory")
}
}
func send(c chan int) {
c <- 1
}
func main() {
}
// $G $D/$F.go && $L $F.$A && ! ./$A.out // $G $D/$F.go && $L $F.$A && ./$A.out
// 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
...@@ -13,6 +13,10 @@ type I interface { ...@@ -13,6 +13,10 @@ type I interface {
} }
func main() { func main() {
shouldPanic(p1)
}
func p1() {
var s *S var s *S
var i I var i I
var e interface {} var e interface {}
...@@ -21,6 +25,14 @@ func main() { ...@@ -21,6 +25,14 @@ func main() {
_ = i _ = i
} }
// hide S down here to avoid static warning
type S struct { type S struct {
} }
func shouldPanic(f func()) {
defer func() {
if recover() == nil {
panic("function should panic")
}
}()
f()
}
// $G $D/$F.go && $L $F.$A && ./$A.out || echo BUG: interface/noeq
// 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.
// Interface values containing types that cannot be compared for equality.
package main
func main() {
cmp(1)
var (
m map[int]int
s struct{ x []int }
f func()
)
noCmp(m)
noCmp(s)
noCmp(f)
}
func cmp(x interface{}) bool {
return x == x
}
func noCmp(x interface{}) {
shouldPanic(func() { cmp(x) })
}
func shouldPanic(f func()) {
defer func() {
if recover() == nil {
panic("function should panic")
}
}()
f()
}
// true # used by recursive2
// 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 I1 interface {
F() I2
}
type I2 interface {
I1
}
// $G $D/recursive1.go && $G $D/$F.go
// 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.
// Check that the mutually recursive types in recursive1.go made it
// intact and with the same meaning, by assigning to or using them.
package main
import "./recursive1"
func main() {
var i1 p.I1
var i2 p.I2
i1 = i2
i2 = i1
i1 = i2.F()
i2 = i1.F()
_, _ = i1, i2
}
// $G $D/$F.go && $L $F.$A && (! ./$A.out || echo BUG: should not succeed) // $G $D/$F.go && $L $F.$A && ./$A.out
// 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
...@@ -18,8 +18,21 @@ type I1 interface { Name() int8 } ...@@ -18,8 +18,21 @@ type I1 interface { Name() int8 }
type I2 interface { Name() int64 } type I2 interface { Name() int64 }
func main() { func main() {
shouldPanic(p1)
}
func p1() {
var i1 I1 var i1 I1
var s *S var s *S
i1 = s i1 = s
print(i1.(I2).Name()) print(i1.(I2).Name())
} }
func shouldPanic(f func()) {
defer func() {
if recover() == nil {
panic("function should panic")
}
}()
f()
}
// $G $D/$F.go && $L $F.$A && ./$A.out // $G $D/$F.go && $L $F.$A && ./$A.out 2>&1 | cmp - $D/$F.out
// 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
......
(+5.000000e+000+6.000000e+000i)
(+5.000000e+000+6.000000e+000i)
(+5.000000e+000+6.000000e+000i)
(+5.000000e+000+6.000000e+000i)
...@@ -105,4 +105,16 @@ func main() { ...@@ -105,4 +105,16 @@ func main() {
println("opcode x", ce, Ce) println("opcode x", ce, Ce)
panic("fail") panic("fail")
} }
r32 := real(complex64(ce))
if r32 != float32(real(Ce)) {
println("real(complex64(ce))", r32, real(Ce))
panic("fail")
}
r64 := real(complex128(ce))
if r64 != real(Ce) {
println("real(complex128(ce))", r64, real(Ce))
panic("fail")
}
} }
...@@ -19,10 +19,29 @@ const ( ...@@ -19,10 +19,29 @@ const (
func main() { func main() {
c0 := C1 c0 := C1
c0 = (c0 + c0 + c0) / (c0 + c0 + 3i) c0 = (c0 + c0 + c0) / (c0 + c0 + 3i)
println(c0) r, i := real(c0), imag(c0)
d := r - 1.292308
if d < 0 {
d = - d
}
if d > 1e-6 {
println(r, "!= 1.292308")
panic(0)
}
d = i + 0.1384615
if d < 0 {
d = - d
}
if d > 1e-6 {
println(i, "!= -0.1384615")
panic(0)
}
c := *(*complex128)(unsafe.Pointer(&c0)) c := *(*complex128)(unsafe.Pointer(&c0))
println(c) if c != c0 {
println(c, "!=", c)
panic(0)
}
var a interface{} var a interface{}
switch c := reflect.ValueOf(a); c.Kind() { switch c := reflect.ValueOf(a); c.Kind() {
......
...@@ -15,30 +15,44 @@ const ( ...@@ -15,30 +15,44 @@ const (
C1 = R + I // ADD(5,6) C1 = R + I // ADD(5,6)
) )
func doprint(c complex128) { fmt.Printf("c = %f\n", c) } func want(s, w string) {
if s != w {
panic(s + " != " + w)
}
}
func doprint(c complex128, w string) {
s := fmt.Sprintf("%f", c)
want(s, w)
}
func main() { func main() {
// constants // constants
fmt.Printf("c = %f\n", -C1) s := fmt.Sprintf("%f", -C1)
doprint(C1) want(s, "(-5.000000-6.000000i)")
doprint(C1, "(5.000000+6.000000i)")
// variables // variables
c1 := C1 c1 := C1
fmt.Printf("c = %f\n", c1) s = fmt.Sprintf("%f", c1)
doprint(c1) want(s, "(5.000000+6.000000i)")
doprint(c1, "(5.000000+6.000000i)")
// 128 // 128
c2 := complex128(C1) c2 := complex128(C1)
fmt.Printf("c = %G\n", c2) s = fmt.Sprintf("%G", c2)
want(s, "(5+6i)")
// real, imag, complex // real, imag, complex
c3 := complex(real(c2)+3, imag(c2)-5) + c2 c3 := complex(real(c2)+3, imag(c2)-5) + c2
fmt.Printf("c = %G\n", c3) s = fmt.Sprintf("%G", c3)
want(s, "(13+7i)")
// compiler used to crash on nested divide // compiler used to crash on nested divide
c4 := complex(real(c3/2), imag(c3/2)) c4 := complex(real(c3/2), imag(c3/2))
if c4 != c3/2 { if c4 != c3/2 {
fmt.Printf("BUG: c3 = %G != c4 = %G\n", c3, c4) fmt.Printf("BUG: c3 = %G != c4 = %G\n", c3, c4)
panic(0)
} }
} }
...@@ -19,36 +19,52 @@ func main() { ...@@ -19,36 +19,52 @@ func main() {
for i := 0; i < len(a); i++ { for i := 0; i < len(a); i++ {
a[i] = complex(float64(i), float64(-i)) a[i] = complex(float64(i), float64(-i))
} }
println(a[5]) if a[5] != 5-5i {
panic(a[5])
}
// slice of complex128 // slice of complex128
s = make([]complex128, len(a)) s = make([]complex128, len(a))
for i := 0; i < len(s); i++ { for i := 0; i < len(s); i++ {
s[i] = a[i] s[i] = a[i]
} }
println(s[5]) if s[5] != 5-5i {
panic(s[5])
}
// chan // chan
c = make(chan complex128) c = make(chan complex128)
go chantest(c) go chantest(c)
println(<-c) vc := <-c
if vc != 5-5i {
panic(vc)
}
// pointer of complex128 // pointer of complex128
v := a[5] v := a[5]
pv := &v pv := &v
println(*pv) if *pv != 5-5i {
panic(*pv)
}
// field of complex128 // field of complex128
f.c = a[5] f.c = a[5]
println(f.c) if f.c != 5-5i {
panic(f.c)
}
// map of complex128 // map of complex128
m = make(map[complex128]complex128) m = make(map[complex128]complex128)
for i := 0; i < len(s); i++ { for i := 0; i < len(s); i++ {
m[-a[i]] = a[i] m[-a[i]] = a[i]
} }
println(m[5i-5]) if m[5i-5] != 5-5i {
println(m[complex(-5, 5)]) panic(m[5i-5])
}
vm := m[complex(-5, 5)]
if vm != 5-5i {
panic(vm)
}
} }
func chantest(c chan complex128) { c <- a[5] } func chantest(c chan complex128) { c <- a[5] }
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
package main package main
type Iputs interface { type Iputs interface {
puts (s string); puts (s string) string;
} }
// --------- // ---------
...@@ -17,9 +17,9 @@ type Print struct { ...@@ -17,9 +17,9 @@ type Print struct {
put Iputs; put Iputs;
} }
func (p *Print) dop() { func (p *Print) dop() string {
print(" print ", p.whoami); r := " print " + string(p.whoami + '0')
p.put.puts("abc"); return r + p.put.puts("abc");
} }
// --------- // ---------
...@@ -29,9 +29,9 @@ type Bio struct { ...@@ -29,9 +29,9 @@ type Bio struct {
put Iputs; put Iputs;
} }
func (b *Bio) puts(s string) { func (b *Bio) puts(s string) string {
print(" bio ", b.whoami); r := " bio " + string(b.whoami + '0')
b.put.puts(s); return r + b.put.puts(s);
} }
// --------- // ---------
...@@ -41,8 +41,8 @@ type File struct { ...@@ -41,8 +41,8 @@ type File struct {
put Iputs; put Iputs;
} }
func (f *File) puts(s string) { func (f *File) puts(s string) string {
print(" file ", f.whoami, " -- ", s); return " file " + string(f.whoami + '0') + " -- " + s
} }
func func
...@@ -59,6 +59,9 @@ main() { ...@@ -59,6 +59,9 @@ main() {
f.whoami = 3; f.whoami = 3;
p.dop(); r := p.dop();
print("\n"); expected := " print 1 bio 2 file 3 -- abc"
if r != expected {
panic(r + " != " + expected)
}
} }
...@@ -4,33 +4,29 @@ ...@@ -4,33 +4,29 @@
// 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
func func main() {
main() { i := 0
i := 0;
if false { if false {
goto gogoloop; goto gogoloop
} }
if false { if false {
goto gogoloop; goto gogoloop
} }
if false { if false {
goto gogoloop; goto gogoloop
} }
goto gogoloop; goto gogoloop
// backward declared // backward declared
loop: loop:
i = i+1; i = i + 1
if i < 100 { if i < 100 {
goto loop; goto loop
} }
print(i); return
print("\n");
return;
gogoloop: gogoloop:
goto loop; goto loop
} }
...@@ -7,61 +7,64 @@ ...@@ -7,61 +7,64 @@
package main package main
type Item interface { type Item interface {
Print(); Print() string
} }
type ListItem struct { type ListItem struct {
item Item; item Item
next *ListItem; next *ListItem
} }
type List struct { type List struct {
head *ListItem; head *ListItem
} }
func (list *List) Init() { func (list *List) Init() {
list.head = nil; list.head = nil
} }
func (list *List) Insert(i Item) { func (list *List) Insert(i Item) {
item := new(ListItem); item := new(ListItem)
item.item = i; item.item = i
item.next = list.head; item.next = list.head
list.head = item; list.head = item
} }
func (list *List) Print() { func (list *List) Print() string {
i := list.head; r := ""
i := list.head
for i != nil { for i != nil {
i.item.Print(); r += i.item.Print()
i = i.next; i = i.next
} }
return r
} }
// Something to put in a list // Something to put in a list
type Integer struct { type Integer struct {
val int; val int
} }
func (this *Integer) Init(i int) *Integer { func (this *Integer) Init(i int) *Integer {
this.val = i; this.val = i
return this; return this
} }
func (this *Integer) Print() { func (this *Integer) Print() string {
print(this.val); return string(this.val + '0')
} }
func func main() {
main() { list := new(List)
list := new(List); list.Init()
list.Init();
for i := 0; i < 10; i = i + 1 { for i := 0; i < 10; i = i + 1 {
integer := new(Integer); integer := new(Integer)
integer.Init(i); integer.Init(i)
list.Insert(integer); list.Insert(integer)
} }
list.Print(); r := list.Print()
print("\n"); if r != "9876543210" {
panic(r)
}
} }
...@@ -4,269 +4,274 @@ ...@@ -4,269 +4,274 @@
// 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
const nilchar = 0; import "fmt"
const nilchar = 0
type Atom struct { type Atom struct {
str string; str string
integer int; integer int
next *Slist; /* in hash bucket */ next *Slist /* in hash bucket */
} }
type List struct { type List struct {
car *Slist; car *Slist
cdr*Slist; cdr *Slist
} }
type Slist struct { type Slist struct {
isatom bool; isatom bool
isstring bool; isstring bool
//union { //union {
atom Atom; atom Atom
list List; list List
//} u; //} u;
} }
func (this *Slist) Car() *Slist { func (this *Slist) Car() *Slist {
return this.list.car; return this.list.car
} }
func (this *Slist) Cdr() *Slist { func (this *Slist) Cdr() *Slist {
return this.list.cdr; return this.list.cdr
} }
func (this *Slist) String() string { func (this *Slist) String() string {
return this.atom.str; return this.atom.str
} }
func (this *Slist) Integer() int { func (this *Slist) Integer() int {
return this.atom.integer; return this.atom.integer
} }
func (slist *Slist) Free() { func (slist *Slist) Free() {
if slist == nil { if slist == nil {
return; return
} }
if slist.isatom { if slist.isatom {
// free(slist.String()); // free(slist.String());
} else { } else {
slist.Car().Free(); slist.Car().Free()
slist.Cdr().Free(); slist.Cdr().Free()
} }
// free(slist); // free(slist);
} }
//Slist* atom(byte *s, int i); //Slist* atom(byte *s, int i);
var token int; var token int
var peekc int = -1; var peekc int = -1
var lineno int32 = 1; var lineno int32 = 1
var input string; var input string
var inputindex int = 0; var inputindex int = 0
var tokenbuf [100]byte; var tokenbuf [100]byte
var tokenlen int = 0; var tokenlen int = 0
const EOF int = -1; const EOF int = -1
func main() { func main() {
var list *Slist; var list *Slist
OpenFile(); OpenFile()
for ;; { for {
list = Parse(); list = Parse()
if list == nil { if list == nil {
break; break
}
r := list.Print()
list.Free()
if r != "(defn foo (add 12 34))" {
panic(r)
} }
list.Print(); break
list.Free();
break;
} }
} }
func (slist *Slist) PrintOne(doparen bool) { func (slist *Slist) PrintOne(doparen bool) string {
if slist == nil { if slist == nil {
return; return ""
} }
var r string
if slist.isatom { if slist.isatom {
if slist.isstring { if slist.isstring {
print(slist.String()); r = slist.String()
} else { } else {
print(slist.Integer()); r = fmt.Sprintf("%v", slist.Integer())
} }
} else { } else {
if doparen { if doparen {
print("(" ); r += "("
} }
slist.Car().PrintOne(true); r += slist.Car().PrintOne(true)
if slist.Cdr() != nil { if slist.Cdr() != nil {
print(" "); r += " "
slist.Cdr().PrintOne(false); r += slist.Cdr().PrintOne(false)
} }
if doparen { if doparen {
print(")"); r += ")"
} }
} }
return r
} }
func (slist *Slist) Print() { func (slist *Slist) Print() string {
slist.PrintOne(true); return slist.PrintOne(true)
print("\n");
} }
func Get() int { func Get() int {
var c int; var c int
if peekc >= 0 { if peekc >= 0 {
c = peekc; c = peekc
peekc = -1; peekc = -1
} else { } else {
c = int(input[inputindex]); c = int(input[inputindex])
inputindex++; inputindex++
if c == '\n' { if c == '\n' {
lineno = lineno + 1; lineno = lineno + 1
} }
if c == nilchar { if c == nilchar {
inputindex = inputindex - 1; inputindex = inputindex - 1
c = EOF; c = EOF
} }
} }
return c; return c
} }
func WhiteSpace(c int) bool { func WhiteSpace(c int) bool {
return c == ' ' || c == '\t' || c == '\r' || c == '\n'; return c == ' ' || c == '\t' || c == '\r' || c == '\n'
} }
func NextToken() { func NextToken() {
var i, c int; var i, c int
tokenbuf[0] = nilchar; // clear previous token tokenbuf[0] = nilchar // clear previous token
c = Get(); c = Get()
for WhiteSpace(c) { for WhiteSpace(c) {
c = Get(); c = Get()
} }
switch c { switch c {
case EOF: case EOF:
token = EOF; token = EOF
case '(', ')': case '(', ')':
token = c; token = c
break; break
default: default:
for i = 0; i < 100 - 1; { // sizeof tokenbuf - 1 for i = 0; i < 100-1; { // sizeof tokenbuf - 1
tokenbuf[i] = byte(c); tokenbuf[i] = byte(c)
i = i + 1; i = i + 1
c = Get(); c = Get()
if c == EOF { if c == EOF {
break; break
} }
if WhiteSpace(c) || c == ')' { if WhiteSpace(c) || c == ')' {
peekc = c; peekc = c
break; break
} }
} }
if i >= 100 - 1 { // sizeof tokenbuf - 1 if i >= 100-1 { // sizeof tokenbuf - 1
panic("atom too long\n"); panic("atom too long\n")
} }
tokenlen = i; tokenlen = i
tokenbuf[i] = nilchar; tokenbuf[i] = nilchar
if '0' <= tokenbuf[0] && tokenbuf[0] <= '9' { if '0' <= tokenbuf[0] && tokenbuf[0] <= '9' {
token = '0'; token = '0'
} else { } else {
token = 'A'; token = 'A'
} }
} }
} }
func Expect(c int) { func Expect(c int) {
if token != c { if token != c {
print("parse error: expected ", c, "\n"); print("parse error: expected ", c, "\n")
panic("parse"); panic("parse")
} }
NextToken(); NextToken()
} }
// Parse a non-parenthesized list up to a closing paren or EOF // Parse a non-parenthesized list up to a closing paren or EOF
func ParseList() *Slist { func ParseList() *Slist {
var slist, retval *Slist; var slist, retval *Slist
slist = new(Slist); slist = new(Slist)
slist.list.car = nil; slist.list.car = nil
slist.list.cdr = nil; slist.list.cdr = nil
slist.isatom = false; slist.isatom = false
slist.isstring = false; slist.isstring = false
retval = slist; retval = slist
for ;; { for {
slist.list.car = Parse(); slist.list.car = Parse()
if token == ')' || token == EOF { // empty cdr if token == ')' || token == EOF { // empty cdr
break; break
} }
slist.list.cdr = new(Slist); slist.list.cdr = new(Slist)
slist = slist.list.cdr; slist = slist.list.cdr
} }
return retval; return retval
} }
func atom(i int) *Slist { // BUG: uses tokenbuf; should take argument) func atom(i int) *Slist { // BUG: uses tokenbuf; should take argument)
var slist *Slist; var slist *Slist
slist = new(Slist); slist = new(Slist)
if token == '0' { if token == '0' {
slist.atom.integer = i; slist.atom.integer = i
slist.isstring = false; slist.isstring = false
} else { } else {
slist.atom.str = string(tokenbuf[0:tokenlen]); slist.atom.str = string(tokenbuf[0:tokenlen])
slist.isstring = true; slist.isstring = true
} }
slist.isatom = true; slist.isatom = true
return slist; return slist
} }
func atoi() int { // BUG: uses tokenbuf; should take argument) func atoi() int { // BUG: uses tokenbuf; should take argument)
var v int = 0; var v int = 0
for i := 0; i < tokenlen && '0' <= tokenbuf[i] && tokenbuf[i] <= '9'; i = i + 1 { for i := 0; i < tokenlen && '0' <= tokenbuf[i] && tokenbuf[i] <= '9'; i = i + 1 {
v = 10 * v + int(tokenbuf[i] - '0'); v = 10*v + int(tokenbuf[i]-'0')
} }
return v; return v
} }
func Parse() *Slist { func Parse() *Slist {
var slist *Slist; var slist *Slist
if token == EOF || token == ')' { if token == EOF || token == ')' {
return nil; return nil
} }
if token == '(' { if token == '(' {
NextToken(); NextToken()
slist = ParseList(); slist = ParseList()
Expect(')'); Expect(')')
return slist; return slist
} else { } else {
// Atom // Atom
switch token { switch token {
case EOF: case EOF:
return nil; return nil
case '0': case '0':
slist = atom(atoi()); slist = atom(atoi())
case '"', 'A': case '"', 'A':
slist = atom(0); slist = atom(0)
default: default:
slist = nil; slist = nil
print("unknown token: ", token, "\n"); print("unknown token: ", token, "\n")
} }
NextToken(); NextToken()
return slist; return slist
} }
return nil; return nil
} }
func OpenFile() { func OpenFile() {
input = "(defn foo (add 12 34))\n\x00"; input = "(defn foo (add 12 34))\n\x00"
inputindex = 0; inputindex = 0
peekc = -1; // BUG peekc = -1 // BUG
NextToken(); NextToken()
} }
// $G $D/$F.go && $L $F.$A && ./$A.out
// 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
func
main() {
print("hello world\n");
}
...@@ -6,19 +6,21 @@ ...@@ -6,19 +6,21 @@
package main package main
func func main() {
main() { r := ""
a := 3; a := 3
for i:=0; i<10; i=i+1 { for i := 0; i < 10; i = i + 1 {
switch(i) { switch i {
case 5: case 5:
print("five"); r += "five"
case a,7: case a, 7:
print("a"); r += "a"
default: default:
print(i); r += string(i + '0')
} }
print("out", i); r += "out" + string(i+'0')
}
if r != "0out01out12out2aout34out4fiveout56out6aout78out89out9" {
panic(r)
} }
print("\n");
} }
// $G $D/$F.go && $L $F.$A && ./$A.out // $G $D/$F.go && $L $F.$A && ./$A.out 2>&1 | cmp - $D/$F.out
// 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
...@@ -71,16 +71,14 @@ func main() { ...@@ -71,16 +71,14 @@ func main() {
/* create string with integer constant */ /* create string with integer constant */
c = string('x') c = string('x')
if c != "x" { if c != "x" {
print("create int ", c) panic("create int " + c)
panic("fail")
} }
/* create string with integer variable */ /* create string with integer variable */
v := 'x' v := 'x'
c = string(v) c = string(v)
if c != "x" { if c != "x" {
print("create int ", c) panic("create int " + c)
panic("fail")
} }
/* create string with byte array */ /* create string with byte array */
...@@ -90,8 +88,7 @@ func main() { ...@@ -90,8 +88,7 @@ func main() {
z1[2] = 'c' z1[2] = 'c'
c = string(z1[0:]) c = string(z1[0:])
if c != "abc" { if c != "abc" {
print("create byte array ", c) panic("create byte array " + c)
panic("fail")
} }
/* create string with int array */ /* create string with int array */
...@@ -101,8 +98,7 @@ func main() { ...@@ -101,8 +98,7 @@ func main() {
z2[2] = 'c' z2[2] = 'c'
c = string(z2[0:]) c = string(z2[0:])
if c != "a\u1234c" { if c != "a\u1234c" {
print("create int array ", c) panic("create int array " + c)
panic("fail")
} }
/* create string with byte array pointer */ /* create string with byte array pointer */
...@@ -112,7 +108,6 @@ func main() { ...@@ -112,7 +108,6 @@ func main() {
z3[2] = 'c' z3[2] = 'c'
c = string(z3[0:]) c = string(z3[0:])
if c != "abc" { if c != "abc" {
print("create array pointer ", c) panic("create array pointer " + c)
panic("fail")
} }
} }
abcxyz-abcxyz-abcxyz-abcxyz-abcxyz-abcxyz-abcxyz
...@@ -47,18 +47,28 @@ func finalB(b *B) { ...@@ -47,18 +47,28 @@ func finalB(b *B) {
nfinal++ nfinal++
} }
func nofinalB(b *B) {
panic("nofinalB run")
}
func main() { func main() {
runtime.GOMAXPROCS(4) runtime.GOMAXPROCS(4)
for i = 0; i < N; i++ { for i = 0; i < N; i++ {
b := &B{i} b := &B{i}
a := &A{b, i} a := &A{b, i}
c := new(B)
runtime.SetFinalizer(c, nofinalB)
runtime.SetFinalizer(b, finalB) runtime.SetFinalizer(b, finalB)
runtime.SetFinalizer(a, finalA) runtime.SetFinalizer(a, finalA)
runtime.SetFinalizer(c, nil)
} }
for i := 0; i < N; i++ { for i := 0; i < N; i++ {
runtime.GC() runtime.GC()
runtime.Gosched() runtime.Gosched()
time.Sleep(1e6) time.Sleep(1e6)
if nfinal >= N*8/10 {
break
}
} }
if nfinal < N*8/10 { if nfinal < N*8/10 {
println("not enough finalizing:", nfinal, "/", N) println("not enough finalizing:", nfinal, "/", N)
......
...@@ -33,6 +33,7 @@ func bigger() { ...@@ -33,6 +33,7 @@ func bigger() {
func main() { func main() {
runtime.GC() // clean up garbage from init runtime.GC() // clean up garbage from init
runtime.UpdateMemStats() // first call can do some allocations
runtime.MemProfileRate = 0 // disable profiler runtime.MemProfileRate = 0 // disable profiler
runtime.MemStats.Alloc = 0 // ignore stacks runtime.MemStats.Alloc = 0 // ignore stacks
flag.Parse() flag.Parse()
......
// errchk $G -e $D/$F.go
// 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.
package main
func main() {}
type v bool
var (
// valid
_ map[int8]v
_ map[uint8]v
_ map[int16]v
_ map[uint16]v
_ map[int32]v
_ map[uint32]v
_ map[int64]v
_ map[uint64]v
_ map[int]v
_ map[uint]v
_ map[uintptr]v
_ map[float32]v
_ map[float64]v
_ map[complex64]v
_ map[complex128]v
_ map[bool]v
_ map[string]v
_ map[chan int]v
_ map[*int]v
_ map[struct{}]v
_ map[[10]int]v
// invalid
_ map[[]int]v // ERROR "invalid map key"
_ map[func()]v // ERROR "invalid map key"
_ map[map[int]int]v // ERROR "invalid map key"
)
...@@ -150,7 +150,7 @@ func maptest() { ...@@ -150,7 +150,7 @@ func maptest() {
m[2] = 3 m[2] = 3
}) })
shouldPanic(func() { shouldPanic(func() {
m[2] = 0, false delete(m, 2)
}) })
} }
......
// $G $D/$F.go && $L $F.$A && ./$A.out
// 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.
package main
import "unsafe"
// Having a big address space means that indexing
// at a 256 MB offset from a nil pointer might not
// cause a memory access fault. This test checks
// that Go is doing the correct explicit checks to catch
// these nil pointer accesses, not just relying on the hardware.
var dummy [256 << 20]byte // give us a big address space
func main() {
// the test only tests what we intend to test
// if dummy starts in the first 256 MB of memory.
// otherwise there might not be anything mapped
// at the address that might be accidentally
// dereferenced below.
if uintptr(unsafe.Pointer(&dummy)) > 256<<20 {
panic("dummy too far out")
}
shouldPanic(p1)
shouldPanic(p2)
shouldPanic(p3)
shouldPanic(p4)
shouldPanic(p5)
shouldPanic(p6)
shouldPanic(p7)
shouldPanic(p8)
shouldPanic(p9)
shouldPanic(p10)
}
func shouldPanic(f func()) {
defer func() {
if recover() == nil {
panic("memory reference did not panic")
}
}()
f()
}
func p1() {
// Array index.
var p *[1 << 30]byte = nil
println(p[256<<20]) // very likely to be inside dummy, but should panic
}
var xb byte
func p2() {
var p *[1 << 30]byte = nil
xb = 123
// Array index.
println(p[uintptr(unsafe.Pointer(&xb))]) // should panic
}
func p3() {
// Array to slice.
var p *[1 << 30]byte = nil
var x []byte = p[0:] // should panic
_ = x
}
var q *[1 << 30]byte
func p4() {
// Array to slice.
var x []byte
var y = &x
*y = q[0:] // should crash (uses arraytoslice runtime routine)
}
func fb([]byte) {
panic("unreachable")
}
func p5() {
// Array to slice.
var p *[1 << 30]byte = nil
fb(p[0:]) // should crash
}
func p6() {
// Array to slice.
var p *[1 << 30]byte = nil
var _ []byte = p[10 : len(p)-10] // should crash
}
type T struct {
x [256 << 20]byte
i int
}
func f() *T {
return nil
}
var y *T
var x = &y
func p7() {
// Struct field access with large offset.
println(f().i) // should crash
}
func p8() {
// Struct field access with large offset.
println((*x).i) // should crash
}
func p9() {
// Struct field access with large offset.
var t *T
println(&t.i) // should crash
}
func p10() {
// Struct field access with large offset.
var t *T
println(t.i) // should crash
}
// $G $D/$F.go && $L $F.$A &&
// ((! sh -c ./$A.out) >/dev/null 2>&1 || echo BUG: should fail)
// 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 "unsafe"
var x byte
func main() {
var p *[1<<30]byte = nil
x = 123
// The problem here is not the use of unsafe:
// it is that indexing into p[] with a large
// enough index jumps out of the unmapped section
// at the beginning of memory and into valid memory.
// Pointer offsets and array indices, if they are
// very large, need to dereference the base pointer
// to trigger a trap.
println(p[uintptr(unsafe.Pointer(&x))]) // should crash
}
// $G $D/$F.go && $L $F.$A &&
// ((! sh -c ./$A.out) >/dev/null 2>&1 || echo BUG: should fail)
// 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 "unsafe"
var dummy [512<<20]byte // give us a big address space
func main() {
// the test only tests what we intend to test
// if dummy starts in the first 256 MB of memory.
// otherwise there might not be anything mapped
// at the address that might be accidentally
// dereferenced below.
if uintptr(unsafe.Pointer(&dummy)) > 256<<20 {
panic("dummy too far out")
}
// The problem here is that indexing into p[] with a large
// enough index jumps out of the unmapped section
// at the beginning of memory and into valid memory.
// Pointer offsets and array indices, if they are
// very large, need to dereference the base pointer
// to trigger a trap.
var p *[1<<30]byte = nil
println(p[256<<20]) // very likely to be inside dummy, but should crash
}
// $G $D/$F.go && $L $F.$A &&
// ((! sh -c ./$A.out) >/dev/null 2>&1 || echo BUG: should fail)
// 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 "unsafe"
func f([]byte) {
panic("unreachable")
}
var dummy [512<<20]byte // give us a big address space
func main() {
// the test only tests what we intend to test
// if dummy starts in the first 256 MB of memory.
// otherwise there might not be anything mapped
// at the address that might be accidentally
// dereferenced below.
if uintptr(unsafe.Pointer(&dummy)) > 256<<20 {
panic("dummy too far out")
}
// The problem here is that indexing into p[] with a large
// enough index can jump out of the unmapped section
// at the beginning of memory and into valid memory.
//
// To avoid needing a check on every slice beyond the
// usual len and cap, we require the *array -> slice
// conversion to do the check.
var p *[1<<30]byte = nil
f(p[0:]) // should crash
}
// $G $D/$F.go && $L $F.$A &&
// ((! sh -c ./$A.out) >/dev/null 2>&1 || echo BUG: should fail)
// 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 "unsafe"
var dummy [512<<20]byte // give us a big address space
func main() {
// the test only tests what we intend to test
// if dummy starts in the first 256 MB of memory.
// otherwise there might not be anything mapped
// at the address that might be accidentally
// dereferenced below.
if uintptr(unsafe.Pointer(&dummy)) > 256<<20 {
panic("dummy too far out")
}
// The problem here is that indexing into p[] with a large
// enough index can jump out of the unmapped section
// at the beginning of memory and into valid memory.
//
// To avoid needing a check on every slice beyond the
// usual len and cap, we require the *array -> slice
// conversion to do the check.
var p *[1<<30]byte = nil
var x []byte = p[0:] // should crash
_ = x
}
// $G $D/$F.go && $L $F.$A &&
// ((! sh -c ./$A.out) >/dev/null 2>&1 || echo BUG: should fail)
// 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 "unsafe"
var dummy [512<<20]byte // give us a big address space
var q *[1<<30]byte
func main() {
// the test only tests what we intend to test
// if dummy starts in the first 256 MB of memory.
// otherwise there might not be anything mapped
// at the address that might be accidentally
// dereferenced below.
if uintptr(unsafe.Pointer(&dummy)) > 256<<20 {
panic("dummy too far out")
}
// The problem here is that indexing into p[] with a large
// enough index can jump out of the unmapped section
// at the beginning of memory and into valid memory.
//
// To avoid needing a check on every slice beyond the
// usual len and cap, we require the *array -> slice
// conversion to do the check.
var x []byte
var y = &x
*y = q[0:] // should crash (uses arraytoslice runtime routine)
}
// $G $D/$F.go && $L $F.$A &&
// ((! sh -c ./$A.out) >/dev/null 2>&1 || echo BUG: should fail)
// 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 "unsafe"
var dummy [512<<20]byte // give us a big address space
func main() {
// the test only tests what we intend to test
// if dummy starts in the first 256 MB of memory.
// otherwise there might not be anything mapped
// at the address that might be accidentally
// dereferenced below.
if uintptr(unsafe.Pointer(&dummy)) > 256<<20 {
panic("dummy too far out")
}
// The problem here is that indexing into p[] with a large
// enough index can jump out of the unmapped section
// at the beginning of memory and into valid memory.
//
// To avoid needing a check on every slice beyond the
// usual len and cap, we require the slice operation
// to do the check.
var p *[1<<30]byte = nil
var _ []byte = p[10:len(p)-10] // should crash
}
// $G $D/$F.go && $L $F.$A &&
// ((! sh -c ./$A.out) >/dev/null 2>&1 || echo BUG: should fail)
// 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 "unsafe"
var dummy [512<<20]byte // give us a big address space
type T struct {
x [256<<20] byte
i int
}
func main() {
// the test only tests what we intend to test
// if dummy starts in the first 256 MB of memory.
// otherwise there might not be anything mapped
// at the address that might be accidentally
// dereferenced below.
if uintptr(unsafe.Pointer(&dummy)) > 256<<20 {
panic("dummy too far out")
}
// The problem here is that indexing into t with a large
// enough index can jump out of the unmapped section
// at the beginning of memory and into valid memory.
// We require the pointer dereference to check.
var t *T
println(t.i) // should crash
}
// $G $D/$F.go && $L $F.$A &&
// ((! sh -c ./$A.out) >/dev/null 2>&1 || echo BUG: should fail)
// 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 "unsafe"
var dummy [512<<20]byte // give us a big address space
type T struct {
x [256<<20] byte
i int
}
func f() *T {
return nil
}
func main() {
// the test only tests what we intend to test
// if dummy starts in the first 256 MB of memory.
// otherwise there might not be anything mapped
// at the address that might be accidentally
// dereferenced below.
if uintptr(unsafe.Pointer(&dummy)) > 256<<20 {
panic("dummy too far out")
}
// The problem here is that indexing into t with a large
// enough index can jump out of the unmapped section
// at the beginning of memory and into valid memory.
// We require the pointer dereference to check.
println(f().i) // should crash
}
// $G $D/$F.go && $L $F.$A &&
// ((! sh -c ./$A.out) >/dev/null 2>&1 || echo BUG: should fail)
// 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 "unsafe"
var dummy [512<<20]byte // give us a big address space
type T struct {
x [256<<20] byte
i int
}
var y *T
var x = &y
func main() {
// the test only tests what we intend to test
// if dummy starts in the first 256 MB of memory.
// otherwise there might not be anything mapped
// at the address that might be accidentally
// dereferenced below.
if uintptr(unsafe.Pointer(&dummy)) > 256<<20 {
panic("dummy too far out")
}
// The problem here is that indexing into t with a large
// enough index can jump out of the unmapped section
// at the beginning of memory and into valid memory.
// We require the pointer dereference to check.
println((*x).i) // should crash
}
// $G $D/$F.go && $L $F.$A &&
// ((! sh -c ./$A.out) >/dev/null 2>&1 || echo BUG: should fail)
// 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 "unsafe"
var dummy [512<<20]byte // give us a big address space
type T struct {
x [256<<20] byte
i int
}
func main() {
// the test only tests what we intend to test
// if dummy starts in the first 256 MB of memory.
// otherwise there might not be anything mapped
// at the address that might be accidentally
// dereferenced below.
if uintptr(unsafe.Pointer(&dummy)) > 256<<20 {
panic("dummy too far out")
}
// The problem here is that indexing into t with a large
// enough index can jump out of the unmapped section
// at the beginning of memory and into valid memory.
// We require the address calculation to check.
var t *T
println(&t.i) // should crash
}
...@@ -8,7 +8,6 @@ package main ...@@ -8,7 +8,6 @@ package main
type Number *Number type Number *Number
// ------------------------------------- // -------------------------------------
// Peano primitives // Peano primitives
...@@ -16,24 +15,20 @@ func zero() *Number { ...@@ -16,24 +15,20 @@ func zero() *Number {
return nil return nil
} }
func is_zero(x *Number) bool { func is_zero(x *Number) bool {
return x == nil return x == nil
} }
func add1(x *Number) *Number { func add1(x *Number) *Number {
e := new(Number) e := new(Number)
*e = x *e = x
return e return e
} }
func sub1(x *Number) *Number { func sub1(x *Number) *Number {
return *x return *x
} }
func add(x, y *Number) *Number { func add(x, y *Number) *Number {
if is_zero(y) { if is_zero(y) {
return x return x
...@@ -42,7 +37,6 @@ func add(x, y *Number) *Number { ...@@ -42,7 +37,6 @@ func add(x, y *Number) *Number {
return add(add1(x), sub1(y)) return add(add1(x), sub1(y))
} }
func mul(x, y *Number) *Number { func mul(x, y *Number) *Number {
if is_zero(x) || is_zero(y) { if is_zero(x) || is_zero(y) {
return zero() return zero()
...@@ -51,7 +45,6 @@ func mul(x, y *Number) *Number { ...@@ -51,7 +45,6 @@ func mul(x, y *Number) *Number {
return add(mul(x, sub1(y)), x) return add(mul(x, sub1(y)), x)
} }
func fact(n *Number) *Number { func fact(n *Number) *Number {
if is_zero(n) { if is_zero(n) {
return add1(zero()) return add1(zero())
...@@ -60,7 +53,6 @@ func fact(n *Number) *Number { ...@@ -60,7 +53,6 @@ func fact(n *Number) *Number {
return mul(fact(sub1(n)), n) return mul(fact(sub1(n)), n)
} }
// ------------------------------------- // -------------------------------------
// Helpers to generate/count Peano integers // Helpers to generate/count Peano integers
...@@ -72,7 +64,6 @@ func gen(n int) *Number { ...@@ -72,7 +64,6 @@ func gen(n int) *Number {
return zero() return zero()
} }
func count(x *Number) int { func count(x *Number) int {
if is_zero(x) { if is_zero(x) {
return 0 return 0
...@@ -81,7 +72,6 @@ func count(x *Number) int { ...@@ -81,7 +72,6 @@ func count(x *Number) int {
return count(sub1(x)) + 1 return count(sub1(x)) + 1
} }
func check(x *Number, expected int) { func check(x *Number, expected int) {
var c = count(x) var c = count(x)
if c != expected { if c != expected {
...@@ -90,7 +80,6 @@ func check(x *Number, expected int) { ...@@ -90,7 +80,6 @@ func check(x *Number, expected int) {
} }
} }
// ------------------------------------- // -------------------------------------
// Test basic functionality // Test basic functionality
...@@ -115,12 +104,19 @@ func init() { ...@@ -115,12 +104,19 @@ func init() {
check(fact(gen(5)), 120) check(fact(gen(5)), 120)
} }
// ------------------------------------- // -------------------------------------
// Factorial // Factorial
var results = [...]int{
1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800,
39916800, 479001600,
}
func main() { func main() {
for i := 0; i <= 9; i++ { for i := 0; i <= 9; i++ {
print(i, "! = ", count(fact(gen(i))), "\n") if f := count(fact(gen(i))); f != results[i] {
println("FAIL:", i, "!:", f, "!=", results[i])
panic(0)
}
} }
} }
// $G $F.go && $L $F.$A && ./$A.out // $G $F.go && $L $F.$A && ./$A.out 2>&1 | cmp - $D/$F.out
// 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
......
-9223372036854775808
9223372036854775807
// $G $D/$F.go && $L $F.$A && ./$A.out
// 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.
// Check reordering of assignments.
package main
import "fmt"
func main() {
p1()
p2()
p3()
p4()
p5()
p6()
p7()
p8()
}
var gx []int
func f(i int) int {
return gx[i]
}
func check(x []int, x0, x1, x2 int) {
if x[0] != x0 || x[1] != x1 || x[2] != x2 {
fmt.Printf("%v, want %d,%d,%d\n", x, x0, x1, x2)
panic("failed")
}
}
func check3(x, y, z, xx, yy, zz int) {
if x != xx || y != yy || z != zz {
fmt.Printf("%d,%d,%d, want %d,%d,%d\n", x, y, z, xx, yy, zz)
panic("failed")
}
}
func p1() {
x := []int{1,2,3}
i := 0
i, x[i] = 1, 100
_ = i
check(x, 100, 2, 3)
}
func p2() {
x := []int{1,2,3}
i := 0
x[i], i = 100, 1
_ = i
check(x, 100, 2, 3)
}
func p3() {
x := []int{1,2,3}
y := x
gx = x
x[1], y[0] = f(0), f(1)
check(x, 2, 1, 3)
}
func p4() {
x := []int{1,2,3}
y := x
gx = x
x[1], y[0] = gx[0], gx[1]
check(x, 2, 1, 3)
}
func p5() {
x := []int{1,2,3}
y := x
p := &x[0]
q := &x[1]
*p, *q = x[1], y[0]
check(x, 2, 1, 3)
}
func p6() {
x := 1
y := 2
z := 3
px := &x
py := &y
*px, *py = y, x
check3(x, y, z, 2, 1, 3)
}
func f1(x, y, z int) (xx, yy, zz int) {
return x, y, z
}
func f2() (x, y, z int) {
return f1(2, 1, 3)
}
func p7() {
x, y, z := f2()
check3(x, y, z, 2, 1, 3)
}
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
}
...@@ -23,7 +23,7 @@ Xarm) ...@@ -23,7 +23,7 @@ Xarm)
exit 1 exit 1
esac esac
export G=${A}g export G="${A}g ${GCFLAGS}"
export L=${A}l export L=${A}l
export GOTRACEBACK=0 export GOTRACEBACK=0
export LANG=C export LANG=C
...@@ -31,7 +31,7 @@ unset GREP_OPTIONS # in case user has a non-standard set ...@@ -31,7 +31,7 @@ unset GREP_OPTIONS # in case user has a non-standard set
failed=0 failed=0
PATH=/bin:/usr/bin:/usr/local/bin:${GOBIN:-$GOROOT/bin}:`pwd` PATH=${GOBIN:-$GOROOT/bin}:`pwd`:/bin:/usr/bin:/usr/local/bin
RUNFILE="/tmp/gorun-$$-$USER" RUNFILE="/tmp/gorun-$$-$USER"
TMP1FILE="/tmp/gotest1-$$-$USER" TMP1FILE="/tmp/gotest1-$$-$USER"
...@@ -53,7 +53,7 @@ filterout() { ...@@ -53,7 +53,7 @@ filterout() {
grep '^'"$2"'$' $1 >/dev/null grep '^'"$2"'$' $1 >/dev/null
} }
for dir in . ken chan interface nilptr syntax fixedbugs bugs for dir in . ken chan interface syntax dwarf fixedbugs bugs
do do
echo echo
echo '==' $dir'/' echo '==' $dir'/'
......
// $G $D/$F.go
// 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.
package main
var (
r0 = 'a'
r1 = 'a'+1
r2 = 1+'a'
r3 = 'a'*2
r4 = 'a'/2
r5 = 'a'<<1
r6 = 'b'<<2
r7 int32
r = []rune{r0, r1, r2, r3, r4, r5, r6, r7}
)
var (
f0 = 1.2
f1 = 1.2/'a'
f = []float64{f0, f1}
)
var (
i0 = 1
i1 = 1<<'\x01'
i = []int{i0, i1}
)
const (
maxRune = '\U0010FFFF'
)
var (
b0 = maxRune < r0
b = []bool{b0}
)
// $G $D/$F.go && $L $F.$A && ./$A.out // [ "$GOOS" == windows ] ||
// ($G $D/$F.go && $L $F.$A && ./$A.out 2>&1 | cmp - $D/$F.out)
// 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
......
// $G -S $D/$F.go | egrep initdone >/dev/null && echo FAIL || true // $G -S $D/$F.go | egrep initdone >/dev/null && echo BUG sinit || true
// 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
...@@ -9,45 +9,45 @@ package p ...@@ -9,45 +9,45 @@ package p
// Should be no init func in the assembly. // Should be no init func in the assembly.
// All these initializations should be done at link time. // All these initializations should be done at link time.
type S struct{ a,b,c int } type S struct{ a, b, c int }
type SS struct{ aa,bb,cc S } type SS struct{ aa, bb, cc S }
type SA struct{ a,b,c [3]int } type SA struct{ a, b, c [3]int }
type SC struct{ a,b,c []int } type SC struct{ a, b, c []int }
var ( var (
zero = 2 zero = 2
one = 1 one = 1
pi = 3.14 pi = 3.14
slice = []byte{1,2,3} slice = []byte{1, 2, 3}
sliceInt = []int{1,2,3} sliceInt = []int{1, 2, 3}
hello = "hello, world" hello = "hello, world"
bytes = []byte("hello, world") bytes = []byte("hello, world")
four, five = 4, 5 four, five = 4, 5
x, y = 0.1, "hello" x, y = 0.1, "hello"
nilslice []byte = nil nilslice []byte = nil
nilmap map[string]int = nil nilmap map[string]int = nil
nilfunc func() = nil nilfunc func() = nil
nilchan chan int = nil nilchan chan int = nil
nilptr *byte = nil nilptr *byte = nil
) )
var a = [3]int{1001, 1002, 1003} var a = [3]int{1001, 1002, 1003}
var s = S{1101, 1102, 1103} var s = S{1101, 1102, 1103}
var c = []int{1201, 1202, 1203} var c = []int{1201, 1202, 1203}
var aa = [3][3]int{[3]int{2001,2002,2003}, [3]int{2004,2005,2006}, [3]int{2007,2008,2009}} var aa = [3][3]int{[3]int{2001, 2002, 2003}, [3]int{2004, 2005, 2006}, [3]int{2007, 2008, 2009}}
var as = [3]S{S{2101,2102,2103},S{2104,2105,2106},S{2107,2108,2109}} var as = [3]S{S{2101, 2102, 2103}, S{2104, 2105, 2106}, S{2107, 2108, 2109}}
var ac = [3][]int{[]int{2201,2202,2203}, []int{2204,2205,2206}, []int{2207,2208,2209}} var ac = [3][]int{[]int{2201, 2202, 2203}, []int{2204, 2205, 2206}, []int{2207, 2208, 2209}}
var sa = SA{[3]int{3001,3002,3003},[3]int{3004,3005,3006},[3]int{3007,3008,3009}} var sa = SA{[3]int{3001, 3002, 3003}, [3]int{3004, 3005, 3006}, [3]int{3007, 3008, 3009}}
var ss = SS{S{3101,3102,3103},S{3104,3105,3106},S{3107,3108,3109}} var ss = SS{S{3101, 3102, 3103}, S{3104, 3105, 3106}, S{3107, 3108, 3109}}
var sc = SC{[]int{3201,3202,3203},[]int{3204,3205,3206},[]int{3207,3208,3209}} var sc = SC{[]int{3201, 3202, 3203}, []int{3204, 3205, 3206}, []int{3207, 3208, 3209}}
var ca = [][3]int{[3]int{4001,4002,4003}, [3]int{4004,4005,4006}, [3]int{4007,4008,4009}} var ca = [][3]int{[3]int{4001, 4002, 4003}, [3]int{4004, 4005, 4006}, [3]int{4007, 4008, 4009}}
var cs = []S{S{4101,4102,4103},S{4104,4105,4106},S{4107,4108,4109}} var cs = []S{S{4101, 4102, 4103}, S{4104, 4105, 4106}, S{4107, 4108, 4109}}
var cc = [][]int{[]int{4201,4202,4203}, []int{4204,4205,4206}, []int{4207,4208,4209}} var cc = [][]int{[]int{4201, 4202, 4203}, []int{4204, 4205, 4206}, []int{4207, 4208, 4209}}
var answers = [...]int { var answers = [...]int{
// s // s
1101, 1102, 1103, 1101, 1102, 1103,
...@@ -98,3 +98,158 @@ var answers = [...]int { ...@@ -98,3 +98,158 @@ var answers = [...]int {
2008, 2208, 2308, 4008, 4208, 4308, 5008, 5208, 5308, 2008, 2208, 2308, 4008, 4208, 4308, 5008, 5208, 5308,
2009, 2209, 2309, 4009, 4209, 4309, 5009, 5209, 5309, 2009, 2209, 2309, 4009, 4209, 4309, 5009, 5209, 5309,
} }
var (
copy_zero = zero
copy_one = one
copy_pi = pi
copy_slice = slice
copy_sliceInt = sliceInt
copy_hello = hello
copy_bytes = bytes
copy_four, copy_five = four, five
copy_x, copy_y = x, y
copy_nilslice = nilslice
copy_nilmap = nilmap
copy_nilfunc = nilfunc
copy_nilchan = nilchan
copy_nilptr = nilptr
)
var copy_a = a
var copy_s = s
var copy_c = c
var copy_aa = aa
var copy_as = as
var copy_ac = ac
var copy_sa = sa
var copy_ss = ss
var copy_sc = sc
var copy_ca = ca
var copy_cs = cs
var copy_cc = cc
var copy_answers = answers
var bx bool
var b0 = false
var b1 = true
var fx float32
var f0 = float32(0)
var f1 = float32(1)
var gx float64
var g0 = float64(0)
var g1 = float64(1)
var ix int
var i0 = 0
var i1 = 1
var jx uint
var j0 = uint(0)
var j1 = uint(1)
var cx complex64
var c0 = complex64(0)
var c1 = complex64(1)
var dx complex128
var d0 = complex128(0)
var d1 = complex128(1)
var sx []int
var s0 = []int{0, 0, 0}
var s1 = []int{1, 2, 3}
func fi() int
var ax [10]int
var a0 = [10]int{0, 0, 0}
var a1 = [10]int{1, 2, 3, 4}
type T struct{ X, Y int }
var tx T
var t0 = T{}
var t0a = T{0, 0}
var t0b = T{X: 0}
var t1 = T{X: 1, Y: 2}
var t1a = T{3, 4}
var psx *[]int
var ps0 = &[]int{0, 0, 0}
var ps1 = &[]int{1, 2, 3}
var pax *[10]int
var pa0 = &[10]int{0, 0, 0}
var pa1 = &[10]int{1, 2, 3}
var ptx *T
var pt0 = &T{}
var pt0a = &T{0, 0}
var pt0b = &T{X: 0}
var pt1 = &T{X: 1, Y: 2}
var pt1a = &T{3, 4}
var copy_bx = bx
var copy_b0 = b0
var copy_b1 = b1
var copy_fx = fx
var copy_f0 = f0
var copy_f1 = f1
var copy_gx = gx
var copy_g0 = g0
var copy_g1 = g1
var copy_ix = ix
var copy_i0 = i0
var copy_i1 = i1
var copy_jx = jx
var copy_j0 = j0
var copy_j1 = j1
var copy_cx = cx
var copy_c0 = c0
var copy_c1 = c1
var copy_dx = dx
var copy_d0 = d0
var copy_d1 = d1
var copy_sx = sx
var copy_s0 = s0
var copy_s1 = s1
var copy_ax = ax
var copy_a0 = a0
var copy_a1 = a1
var copy_tx = tx
var copy_t0 = t0
var copy_t0a = t0a
var copy_t0b = t0b
var copy_t1 = t1
var copy_t1a = t1a
var copy_psx = psx
var copy_ps0 = ps0
var copy_ps1 = ps1
var copy_pax = pax
var copy_pa0 = pa0
var copy_pa1 = pa1
var copy_ptx = ptx
var copy_pt0 = pt0
var copy_pt0a = pt0a
var copy_pt0b = pt0b
var copy_pt1 = pt1
var copy_pt1a = pt1a
// $G $D/$F.go && $L $F.$A && ./$A.out
// 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.
// zero length structs.
// used to not be evaluated.
// issue 2232.
package main
func recv(c chan interface{}) struct{} {
return (<-c).(struct{})
}
var m = make(map[interface{}]int)
func recv1(c chan interface{}) {
defer rec()
m[(<-c).(struct{})] = 0
}
func rec() {
recover()
}
func main() {
c := make(chan interface{})
go recv(c)
c <- struct{}{}
go recv1(c)
c <- struct{}{}
}
...@@ -19,48 +19,75 @@ func main() { ...@@ -19,48 +19,75 @@ func main() {
hello := "hello" hello := "hello"
switch true { switch true {
case i5 < 5: assert(false, "<") case i5 < 5:
case i5 == 5: assert(true, "!") assert(false, "<")
case i5 > 5: assert(false, ">") case i5 == 5:
assert(true, "!")
case i5 > 5:
assert(false, ">")
} }
switch { switch {
case i5 < 5: assert(false, "<") case i5 < 5:
case i5 == 5: assert(true, "!") assert(false, "<")
case i5 > 5: assert(false, ">") case i5 == 5:
assert(true, "!")
case i5 > 5:
assert(false, ">")
} }
switch x := 5; true { switch x := 5; true {
case i5 < x: assert(false, "<") case i5 < x:
case i5 == x: assert(true, "!") assert(false, "<")
case i5 > x: assert(false, ">") case i5 == x:
assert(true, "!")
case i5 > x:
assert(false, ">")
} }
switch x := 5; true { switch x := 5; true {
case i5 < x: assert(false, "<") case i5 < x:
case i5 == x: assert(true, "!") assert(false, "<")
case i5 > x: assert(false, ">") case i5 == x:
assert(true, "!")
case i5 > x:
assert(false, ">")
} }
switch i5 { switch i5 {
case 0: assert(false, "0") case 0:
case 1: assert(false, "1") assert(false, "0")
case 2: assert(false, "2") case 1:
case 3: assert(false, "3") assert(false, "1")
case 4: assert(false, "4") case 2:
case 5: assert(true, "5") assert(false, "2")
case 6: assert(false, "6") case 3:
case 7: assert(false, "7") assert(false, "3")
case 8: assert(false, "8") case 4:
case 9: assert(false, "9") assert(false, "4")
default: assert(false, "default") case 5:
assert(true, "5")
case 6:
assert(false, "6")
case 7:
assert(false, "7")
case 8:
assert(false, "8")
case 9:
assert(false, "9")
default:
assert(false, "default")
} }
switch i5 { switch i5 {
case 0,1,2,3,4: assert(false, "4") case 0, 1, 2, 3, 4:
case 5: assert(true, "5") assert(false, "4")
case 6,7,8,9: assert(false, "9") case 5:
default: assert(false, "default") assert(true, "5")
case 6, 7, 8, 9:
assert(false, "9")
default:
assert(false, "default")
} }
switch i5 { switch i5 {
...@@ -68,72 +95,188 @@ func main() { ...@@ -68,72 +95,188 @@ func main() {
case 1: case 1:
case 2: case 2:
case 3: case 3:
case 4: assert(false, "4") case 4:
case 5: assert(true, "5") assert(false, "4")
case 5:
assert(true, "5")
case 6: case 6:
case 7: case 7:
case 8: case 8:
case 9: case 9:
default: assert(i5 == 5, "good") default:
assert(i5 == 5, "good")
} }
switch i5 { switch i5 {
case 0: dummy := 0; _ = dummy; fallthrough case 0:
case 1: dummy := 0; _ = dummy; fallthrough dummy := 0
case 2: dummy := 0; _ = dummy; fallthrough _ = dummy
case 3: dummy := 0; _ = dummy; fallthrough fallthrough
case 4: dummy := 0; _ = dummy; assert(false, "4") case 1:
case 5: dummy := 0; _ = dummy; fallthrough dummy := 0
case 6: dummy := 0; _ = dummy; fallthrough _ = dummy
case 7: dummy := 0; _ = dummy; fallthrough fallthrough
case 8: dummy := 0; _ = dummy; fallthrough case 2:
case 9: dummy := 0; _ = dummy; fallthrough dummy := 0
default: dummy := 0; _ = dummy; assert(i5 == 5, "good") _ = dummy
fallthrough
case 3:
dummy := 0
_ = dummy
fallthrough
case 4:
dummy := 0
_ = dummy
assert(false, "4")
case 5:
dummy := 0
_ = dummy
fallthrough
case 6:
dummy := 0
_ = dummy
fallthrough
case 7:
dummy := 0
_ = dummy
fallthrough
case 8:
dummy := 0
_ = dummy
fallthrough
case 9:
dummy := 0
_ = dummy
fallthrough
default:
dummy := 0
_ = dummy
assert(i5 == 5, "good")
} }
fired := false fired := false
switch i5 { switch i5 {
case 0: dummy := 0; _ = dummy; fallthrough; // tests scoping of cases case 0:
case 1: dummy := 0; _ = dummy; fallthrough dummy := 0
case 2: dummy := 0; _ = dummy; fallthrough _ = dummy
case 3: dummy := 0; _ = dummy; fallthrough fallthrough // tests scoping of cases
case 4: dummy := 0; _ = dummy; assert(false, "4") case 1:
case 5: dummy := 0; _ = dummy; fallthrough dummy := 0
case 6: dummy := 0; _ = dummy; fallthrough _ = dummy
case 7: dummy := 0; _ = dummy; fallthrough fallthrough
case 8: dummy := 0; _ = dummy; fallthrough case 2:
case 9: dummy := 0; _ = dummy; fallthrough dummy := 0
default: dummy := 0; _ = dummy; fired = !fired; assert(i5 == 5, "good") _ = dummy
fallthrough
case 3:
dummy := 0
_ = dummy
fallthrough
case 4:
dummy := 0
_ = dummy
assert(false, "4")
case 5:
dummy := 0
_ = dummy
fallthrough
case 6:
dummy := 0
_ = dummy
fallthrough
case 7:
dummy := 0
_ = dummy
fallthrough
case 8:
dummy := 0
_ = dummy
fallthrough
case 9:
dummy := 0
_ = dummy
fallthrough
default:
dummy := 0
_ = dummy
fired = !fired
assert(i5 == 5, "good")
} }
assert(fired, "fired") assert(fired, "fired")
count := 0 count := 0
switch i5 { switch i5 {
case 0: count = count + 1; fallthrough case 0:
case 1: count = count + 1; fallthrough count = count + 1
case 2: count = count + 1; fallthrough fallthrough
case 3: count = count + 1; fallthrough case 1:
case 4: count = count + 1; assert(false, "4") count = count + 1
case 5: count = count + 1; fallthrough fallthrough
case 6: count = count + 1; fallthrough case 2:
case 7: count = count + 1; fallthrough count = count + 1
case 8: count = count + 1; fallthrough fallthrough
case 9: count = count + 1; fallthrough case 3:
default: assert(i5 == count, "good") count = count + 1
fallthrough
case 4:
count = count + 1
assert(false, "4")
case 5:
count = count + 1
fallthrough
case 6:
count = count + 1
fallthrough
case 7:
count = count + 1
fallthrough
case 8:
count = count + 1
fallthrough
case 9:
count = count + 1
fallthrough
default:
assert(i5 == count, "good")
} }
assert(fired, "fired") assert(fired, "fired")
switch hello { switch hello {
case "wowie": assert(false, "wowie") case "wowie":
case "hello": assert(true, "hello") assert(false, "wowie")
case "jumpn": assert(false, "jumpn") case "hello":
default: assert(false, "default") assert(true, "hello")
case "jumpn":
assert(false, "jumpn")
default:
assert(false, "default")
} }
fired = false fired = false
switch i := i5 + 2; i { switch i := i5 + 2; i {
case i7: fired = true case i7:
default: assert(false, "fail") fired = true
default:
assert(false, "fail")
} }
assert(fired, "var") assert(fired, "var")
// switch on nil-only comparison types
switch f := func() {}; f {
case nil:
assert(false, "f should not be nil")
default:
}
switch m := make(map[int]int); m {
case nil:
assert(false, "m should not be nil")
default:
}
switch a := make([]int, 1); a {
case nil:
assert(false, "m should not be nil")
default:
}
} }
// errchk $G -e $D/$F.go
// 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.
package main
type I interface {
M()
}
func bad() {
var i I
var s string
switch i {
case s: // ERROR "mismatched types string and I|incompatible types"
}
switch s {
case i: // ERROR "mismatched types I and string|incompatible types"
}
var m, m1 map[int]int
switch m {
case nil:
case m1: // ERROR "can only compare map m to nil|map can only be compared to nil"
default:
}
var a, a1 []int
switch a {
case nil:
case a1: // ERROR "can only compare slice a to nil|slice can only be compared to nil"
default:
}
var f, f1 func()
switch f {
case nil:
case f1: // ERROR "can only compare func f to nil|func can only be compared to nil"
default:
}
}
func good() {
var i interface{}
var s string
switch i {
case s:
}
switch s {
case i:
}
}
// errchk $G $D/$F.go
// 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.
package main
func main() {
if true {
} else ; // ERROR "else must be followed by if or statement block|expected .if. or .{."
}
0.04 ./235
1.72 ./64bit
0.03 ./alias
0.03 ./alias1
0.30 ./append
0.07 ./args
0.02 ./assign
0.04 ./assign1
0.04 ./bigalg
0.03 ./bigmap
0.14 ./blank
0.03 ./blank1
0.03 ./chancap
0.07 ./char_lit
0.03 ./char_lit1
0.09 ./closedchan
0.05 ./closure
0.06 ./cmp
0.02 ./cmp6
0.03 ./cmplx
0.60 ./cmplxdivide
0.00 ./cmplxdivide1
0.04 ./complit
0.02 ./complit1
0.03 ./compos
0.04 ./const
0.03 ./const1
0.03 ./const2
0.13 ./const3
0.08 ./convert
0.03 ./convert1
0.02 ./convert3
0.04 ./convlit
0.02 ./convlit1
0.34 ./copy
0.27 ./crlf
0.05 ./ddd
0.02 ./ddd1
0.00 ./ddd2
0.04 ./ddd3
0.03 ./decl
0.03 ./declbad
0.14 ./defer
0.03 ./deferprint
0.14 ./divide
0.00 ./empty
0.08 ./env
0.00 ./eof
0.00 ./eof1
0.04 ./escape
0.12 ./escape2
0.03 ./escape3
0.05 ./float_lit
0.14 ./floatcmp
0.03 ./for
0.04 ./func
0.03 ./func1
0.00 ./func2
0.03 ./func3
0.03 ./func4
0.03 ./func5
0.00 ./func6
0.04 ./func7
0.03 ./gc
0.04 ./gc1
0.26 ./gc2
0.06 ./goprint
0.04 ./goto
0.04 ./hashmap
0.03 ./helloworld
0.03 ./if
0.02 ./import
0.15 ./import1
0.00 ./import2
0.01 ./import3
0.14 ./import4
1.70 ./index
0.03 ./indirect
0.02 ./indirect1
0.02 ./init
0.25 ./init1
0.03 ./initcomma
0.15 ./initialize
0.02 ./initializerr
0.06 ./initsyscall
0.07 ./int_lit
0.03 ./intcvt
0.03 ./iota
0.03 ./label
0.03 ./label1
0.04 ./literal
0.15 ./malloc1
0.06 ./mallocfin
0.19 ./mallocrand
0.21 ./mallocrep
0.52 ./mallocrep1
0.17 ./map
0.02 ./map1
0.05 ./method
0.02 ./method1
0.03 ./method2
0.04 ./method3
0.06 ./named
0.03 ./named1
0.18 ./nil
0.15 ./nilptr
0.16 ./nul1
0.00 ./parentype
0.11 ./peano
0.02 ./printbig
0.05 ./range
0.04 ./recover
0.04 ./recover1
0.08 ./recover2
0.06 ./recover3
0.14 ./rename
0.02 ./rename1
0.16 ./reorder
0.00 ./rune
0.03 ./runtime
0.03 ./shift1
0.01 ./shift2
0.03 ./sieve
0.06 ./sigchld
0.03 ./simassign
0.02 ./sinit
0.00 ./sizeof
0.03 ./solitaire
0.06 ./stack
0.08 ./string_lit
0.14 ./stringrange
0.04 ./struct0
0.04 ./switch
0.08 ./switch1
0.02 ./switch3
0.04 ./test0
0.03 ./turing
0.07 ./typeswitch
0.15 ./typeswitch1
0.02 ./typeswitch2
0.03 ./typeswitch3
0.02 ./undef
0.04 ./utf
0.03 ./varerr
0.03 ./varinit
0.26 ./zerodivide
0.04 ken/array
0.11 ken/chan
0.04 ken/chan1
0.04 ken/complit
0.07 ken/convert
0.03 ken/cplx0
0.02 ken/cplx1
0.06 ken/cplx2
0.09 ken/cplx3
0.14 ken/cplx4
0.03 ken/cplx5
0.31 ken/divconst
0.05 ken/divmod
0.04 ken/embed
0.03 ken/for
0.04 ken/interbasic
0.03 ken/interfun
0.04 ken/intervar
0.03 ken/label
0.03 ken/litfun
0.03 ken/mfunc
0.34 ken/modconst
0.03 ken/ptrfun
0.03 ken/ptrvar
0.04 ken/range
0.03 ken/rob1
0.18 ken/rob2
0.04 ken/robfor
0.04 ken/robfunc
0.03 ken/shift
0.03 ken/simparray
0.04 ken/simpbool
0.03 ken/simpconv
0.03 ken/simpfun
0.03 ken/simpswitch
0.03 ken/simpvar
0.02 ken/slicearray
0.03 ken/sliceslice
0.03 ken/string
0.03 ken/strvar
0.32 chan/doubleselect
0.06 chan/fifo
0.12 chan/goroutines
0.07 chan/nonblock
0.02 chan/perm
0.10 chan/powser1
0.09 chan/powser2
0.03 chan/select
0.15 chan/select2
0.97 chan/select3
0.03 chan/select4
0.72 chan/select5
0.03 chan/select6
0.04 chan/select7
0.03 chan/sendstmt
0.03 chan/sieve1
0.04 chan/sieve2
0.02 chan/zerosize
0.04 interface/bigdata
0.04 interface/convert
0.03 interface/convert1
0.03 interface/convert2
0.09 interface/embed
0.00 interface/embed0
0.03 interface/embed1
0.02 interface/embed2
0.02 interface/explicit
0.03 interface/fail
0.09 interface/fake
0.03 interface/noeq
0.03 interface/pointer
0.03 interface/private
0.00 interface/private1
0.04 interface/receiver
0.03 interface/receiver1
0.00 interface/recursive
0.03 interface/returntype
0.09 interface/struct
0.02 syntax/chan
0.03 syntax/chan1
0.02 syntax/else
0.02 syntax/forvar
0.03 syntax/if
0.03 syntax/import
0.03 syntax/interface
0.03 syntax/semi1
0.02 syntax/semi2
0.03 syntax/semi3
0.03 syntax/semi4
0.02 syntax/semi5
0.03 syntax/semi6
0.02 syntax/semi7
0.02 syntax/topexpr
0.03 syntax/typesw
0.02 syntax/vareq
0.03 syntax/vareq1
0.04 dwarf/linedirectives
0.05 dwarf/main
0.00 dwarf/z1
0.00 dwarf/z10
0.00 dwarf/z11
0.00 dwarf/z12
0.00 dwarf/z13
0.00 dwarf/z14
0.00 dwarf/z15
0.00 dwarf/z16
0.00 dwarf/z17
0.00 dwarf/z18
0.00 dwarf/z19
0.00 dwarf/z2
0.00 dwarf/z20
0.00 dwarf/z3
0.00 dwarf/z4
0.00 dwarf/z5
0.00 dwarf/z6
0.00 dwarf/z7
0.00 dwarf/z8
0.00 dwarf/z9
0.03 fixedbugs/bug000
0.03 fixedbugs/bug002
0.03 fixedbugs/bug003
0.03 fixedbugs/bug004
0.04 fixedbugs/bug005
0.08 fixedbugs/bug006
0.03 fixedbugs/bug007
0.03 fixedbugs/bug008
0.02 fixedbugs/bug009
0.03 fixedbugs/bug010
0.03 fixedbugs/bug011
0.03 fixedbugs/bug012
0.03 fixedbugs/bug013
0.03 fixedbugs/bug014
0.02 fixedbugs/bug015
0.02 fixedbugs/bug016
0.03 fixedbugs/bug017
0.00 fixedbugs/bug020
0.03 fixedbugs/bug021
0.02 fixedbugs/bug022
0.03 fixedbugs/bug023
0.03 fixedbugs/bug024
0.03 fixedbugs/bug026
0.14 fixedbugs/bug027
0.03 fixedbugs/bug028
0.02 fixedbugs/bug030
0.03 fixedbugs/bug031
0.02 fixedbugs/bug035
0.00 fixedbugs/bug036
0.02 fixedbugs/bug037
0.00 fixedbugs/bug038
0.03 fixedbugs/bug039
0.00 fixedbugs/bug040
0.03 fixedbugs/bug045
0.03 fixedbugs/bug046
0.03 fixedbugs/bug047
0.02 fixedbugs/bug048
0.03 fixedbugs/bug049
0.03 fixedbugs/bug050
0.02 fixedbugs/bug051
0.03 fixedbugs/bug052
0.03 fixedbugs/bug053
0.03 fixedbugs/bug054
0.03 fixedbugs/bug055
0.03 fixedbugs/bug056
0.00 fixedbugs/bug057
0.04 fixedbugs/bug058
0.08 fixedbugs/bug059
0.08 fixedbugs/bug060
0.03 fixedbugs/bug061
0.03 fixedbugs/bug062
0.00 fixedbugs/bug063
0.00 fixedbugs/bug064
0.03 fixedbugs/bug065
0.00 fixedbugs/bug066
0.03 fixedbugs/bug067
0.03 fixedbugs/bug068
0.00 fixedbugs/bug069
0.15 fixedbugs/bug070
0.00 fixedbugs/bug071
0.03 fixedbugs/bug072
0.03 fixedbugs/bug073
0.03 fixedbugs/bug074
0.03 fixedbugs/bug075
0.03 fixedbugs/bug076
0.00 fixedbugs/bug077
0.03 fixedbugs/bug078
0.00 fixedbugs/bug080
0.02 fixedbugs/bug081
0.03 fixedbugs/bug082
0.03 fixedbugs/bug083
0.04 fixedbugs/bug084
0.02 fixedbugs/bug085
0.03 fixedbugs/bug086
0.00 fixedbugs/bug087
0.01 fixedbugs/bug088
0.00 fixedbugs/bug089
0.03 fixedbugs/bug090
0.02 fixedbugs/bug091
0.03 fixedbugs/bug092
0.03 fixedbugs/bug093
0.00 fixedbugs/bug094
0.00 fixedbugs/bug096
0.03 fixedbugs/bug097
0.00 fixedbugs/bug098
0.03 fixedbugs/bug099
0.03 fixedbugs/bug101
0.03 fixedbugs/bug102
0.02 fixedbugs/bug103
0.03 fixedbugs/bug104
0.01 fixedbugs/bug106
0.03 fixedbugs/bug107
0.03 fixedbugs/bug108
0.00 fixedbugs/bug109
0.03 fixedbugs/bug110
0.03 fixedbugs/bug111
0.00 fixedbugs/bug112
0.03 fixedbugs/bug113
0.03 fixedbugs/bug114
0.00 fixedbugs/bug115
0.03 fixedbugs/bug116
0.02 fixedbugs/bug117
0.00 fixedbugs/bug118
0.03 fixedbugs/bug119
0.11 fixedbugs/bug120
0.02 fixedbugs/bug121
0.03 fixedbugs/bug122
0.03 fixedbugs/bug123
0.02 fixedbugs/bug126
0.02 fixedbugs/bug127
0.03 fixedbugs/bug128
0.01 fixedbugs/bug129
0.08 fixedbugs/bug130
0.02 fixedbugs/bug131
0.02 fixedbugs/bug132
0.03 fixedbugs/bug133
0.00 fixedbugs/bug135
0.02 fixedbugs/bug136
0.00 fixedbugs/bug137
0.00 fixedbugs/bug139
0.00 fixedbugs/bug140
0.07 fixedbugs/bug141
0.03 fixedbugs/bug142
0.00 fixedbugs/bug143
0.00 fixedbugs/bug144
0.00 fixedbugs/bug145
0.03 fixedbugs/bug146
0.06 fixedbugs/bug147
0.03 fixedbugs/bug148
0.00 fixedbugs/bug149
0.00 fixedbugs/bug150
0.00 fixedbugs/bug151
0.03 fixedbugs/bug1515
0.03 fixedbugs/bug152
0.14 fixedbugs/bug154
0.03 fixedbugs/bug155
0.00 fixedbugs/bug156
0.00 fixedbugs/bug157
0.00 fixedbugs/bug158
0.07 fixedbugs/bug159
0.09 fixedbugs/bug160
0.00 fixedbugs/bug161
0.02 fixedbugs/bug163
0.00 fixedbugs/bug164
0.03 fixedbugs/bug165
0.03 fixedbugs/bug167
0.03 fixedbugs/bug168
0.02 fixedbugs/bug169
0.03 fixedbugs/bug170
0.03 fixedbugs/bug171
0.02 fixedbugs/bug172
0.00 fixedbugs/bug173
0.00 fixedbugs/bug174
0.03 fixedbugs/bug175
0.03 fixedbugs/bug176
0.09 fixedbugs/bug177
0.03 fixedbugs/bug178
0.03 fixedbugs/bug179
0.03 fixedbugs/bug180
0.03 fixedbugs/bug181
0.02 fixedbugs/bug182
0.03 fixedbugs/bug183
0.15 fixedbugs/bug184
0.04 fixedbugs/bug185
0.02 fixedbugs/bug186
0.08 fixedbugs/bug187
0.03 fixedbugs/bug188
0.03 fixedbugs/bug189
0.00 fixedbugs/bug190
0.04 fixedbugs/bug191
0.03 fixedbugs/bug192
0.03 fixedbugs/bug193
0.03 fixedbugs/bug194
0.02 fixedbugs/bug195
0.04 fixedbugs/bug196
0.02 fixedbugs/bug197
0.03 fixedbugs/bug198
0.03 fixedbugs/bug199
0.03 fixedbugs/bug200
0.03 fixedbugs/bug201
0.03 fixedbugs/bug202
0.03 fixedbugs/bug203
0.03 fixedbugs/bug204
0.02 fixedbugs/bug205
0.21 fixedbugs/bug206
0.14 fixedbugs/bug207
0.02 fixedbugs/bug208
0.02 fixedbugs/bug209
0.03 fixedbugs/bug211
0.03 fixedbugs/bug212
0.03 fixedbugs/bug213
0.00 fixedbugs/bug214
0.02 fixedbugs/bug215
0.00 fixedbugs/bug216
0.03 fixedbugs/bug217
0.00 fixedbugs/bug218
0.00 fixedbugs/bug219
0.04 fixedbugs/bug221
0.01 fixedbugs/bug222
0.00 fixedbugs/bug223
0.03 fixedbugs/bug224
0.03 fixedbugs/bug225
0.03 fixedbugs/bug227
0.03 fixedbugs/bug228
0.03 fixedbugs/bug229
0.03 fixedbugs/bug230
0.02 fixedbugs/bug231
0.00 fixedbugs/bug232
0.01 fixedbugs/bug233
0.04 fixedbugs/bug234
0.00 fixedbugs/bug235
0.04 fixedbugs/bug236
0.15 fixedbugs/bug237
0.03 fixedbugs/bug238
0.00 fixedbugs/bug239
0.03 fixedbugs/bug240
0.03 fixedbugs/bug241
0.04 fixedbugs/bug242
0.04 fixedbugs/bug243
0.03 fixedbugs/bug244
0.00 fixedbugs/bug245
0.03 fixedbugs/bug246
0.03 fixedbugs/bug247
0.11 fixedbugs/bug248
0.03 fixedbugs/bug249
0.00 fixedbugs/bug250
0.03 fixedbugs/bug251
0.03 fixedbugs/bug252
0.03 fixedbugs/bug253
0.03 fixedbugs/bug254
0.03 fixedbugs/bug255
0.03 fixedbugs/bug256
0.47 fixedbugs/bug257
0.14 fixedbugs/bug258
0.16 fixedbugs/bug259
0.16 fixedbugs/bug260
0.03 fixedbugs/bug261
0.10 fixedbugs/bug262
0.03 fixedbugs/bug263
0.03 fixedbugs/bug264
0.07 fixedbugs/bug265
0.03 fixedbugs/bug266
0.00 fixedbugs/bug267
0.03 fixedbugs/bug269
0.13 fixedbugs/bug271
0.02 fixedbugs/bug272
0.04 fixedbugs/bug273
0.02 fixedbugs/bug274
0.00 fixedbugs/bug275
0.03 fixedbugs/bug276
0.00 fixedbugs/bug277
0.03 fixedbugs/bug278
0.04 fixedbugs/bug279
0.02 fixedbugs/bug280
0.04 fixedbugs/bug281
0.00 fixedbugs/bug282
0.00 fixedbugs/bug283
0.03 fixedbugs/bug284
0.05 fixedbugs/bug285
0.04 fixedbugs/bug286
0.02 fixedbugs/bug287
0.00 fixedbugs/bug288
0.02 fixedbugs/bug289
0.04 fixedbugs/bug290
0.04 fixedbugs/bug291
0.03 fixedbugs/bug292
0.04 fixedbugs/bug293
0.03 fixedbugs/bug294
0.16 fixedbugs/bug295
0.04 fixedbugs/bug296
0.03 fixedbugs/bug297
0.03 fixedbugs/bug298
0.03 fixedbugs/bug299
0.03 fixedbugs/bug300
0.00 fixedbugs/bug301
0.04 fixedbugs/bug302
0.05 fixedbugs/bug303
0.00 fixedbugs/bug304
0.03 fixedbugs/bug305
0.01 fixedbugs/bug306
0.00 fixedbugs/bug307
0.01 fixedbugs/bug308
0.00 fixedbugs/bug309
0.04 fixedbugs/bug311
0.03 fixedbugs/bug312
0.04 fixedbugs/bug313
0.04 fixedbugs/bug314
0.00 fixedbugs/bug315
0.00 fixedbugs/bug316
0.03 fixedbugs/bug317
0.03 fixedbugs/bug318
0.00 fixedbugs/bug319
0.03 fixedbugs/bug320
0.14 fixedbugs/bug321
0.04 fixedbugs/bug322
0.03 fixedbugs/bug323
0.04 fixedbugs/bug324
0.03 fixedbugs/bug325
0.02 fixedbugs/bug326
0.04 fixedbugs/bug327
0.03 fixedbugs/bug328
0.04 fixedbugs/bug329
0.02 fixedbugs/bug330
0.04 fixedbugs/bug331
0.02 fixedbugs/bug332
0.03 fixedbugs/bug333
0.01 fixedbugs/bug334
0.01 fixedbugs/bug335
0.04 fixedbugs/bug336
0.03 fixedbugs/bug337
0.00 fixedbugs/bug338
0.03 fixedbugs/bug339
0.02 fixedbugs/bug340
0.03 fixedbugs/bug341
0.02 fixedbugs/bug342
0.04 fixedbugs/bug343
0.02 fixedbugs/bug344
0.03 fixedbugs/bug345
0.08 fixedbugs/bug346
0.04 fixedbugs/bug347
0.06 fixedbugs/bug348
0.03 fixedbugs/bug349
0.03 fixedbugs/bug350
0.02 fixedbugs/bug351
0.03 fixedbugs/bug352
0.03 fixedbugs/bug353
0.00 fixedbugs/bug354
0.03 fixedbugs/bug355
0.03 fixedbugs/bug356
0.02 fixedbugs/bug357
0.04 fixedbugs/bug358
0.00 fixedbugs/bug361
0.03 fixedbugs/bug362
0.03 fixedbugs/bug363
0.15 fixedbugs/bug364
0.02 fixedbugs/bug365
0.03 fixedbugs/bug366
0.03 fixedbugs/bug367
0.03 fixedbugs/bug368
0.51 fixedbugs/bug369
0.03 fixedbugs/bug370
0.02 fixedbugs/bug371
0.03 fixedbugs/bug372
0.03 fixedbugs/bug373
0.03 fixedbugs/bug374
0.03 fixedbugs/bug375
0.03 fixedbugs/bug376
0.01 fixedbugs/bug377
0.03 fixedbugs/bug378
0.02 fixedbugs/bug379
0.00 fixedbugs/bug380
0.03 fixedbugs/bug381
0.01 fixedbugs/bug382
0.03 fixedbugs/bug383
0.03 fixedbugs/bug384
0.00 fixedbugs/bug385_32
0.03 fixedbugs/bug385_64
0.03 fixedbugs/bug386
0.01 fixedbugs/bug387
0.02 fixedbugs/bug388
0.03 fixedbugs/bug389
0.03 fixedbugs/bug390
0.00 fixedbugs/bug391
0.01 fixedbugs/bug392
0.00 fixedbugs/bug393
0.03 fixedbugs/bug394
0.00 fixedbugs/bug395
0.01 fixedbugs/bug396
...@@ -10,42 +10,47 @@ package main ...@@ -10,42 +10,47 @@ package main
var p, pc int var p, pc int
var a [30000]byte var a [30000]byte
const prog = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.!" const prog = "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.!"
func scan(dir int) { func scan(dir int) {
for nest := dir; dir*nest > 0; pc += dir { for nest := dir; dir*nest > 0; pc += dir {
switch prog[pc+dir] { switch prog[pc+dir] {
case ']': case ']':
nest-- nest--
case '[': case '[':
nest++ nest++
} }
} }
} }
func main() { func main() {
r := ""
for { for {
switch prog[pc] { switch prog[pc] {
case '>': case '>':
p++ p++
case '<': case '<':
p-- p--
case '+': case '+':
a[p]++ a[p]++
case '-': case '-':
a[p]-- a[p]--
case '.': case '.':
print(string(a[p])) r += string(a[p])
case '[': case '[':
if a[p] == 0 { if a[p] == 0 {
scan(1) scan(1)
} }
case ']': case ']':
if a[p] != 0 { if a[p] != 0 {
scan(-1) scan(-1)
} }
default: default:
return if r != "Hello World!\n" {
panic(r)
}
return
} }
pc++ pc++
} }
......
...@@ -18,11 +18,27 @@ func whatis(x interface{}) string { ...@@ -18,11 +18,27 @@ func whatis(x interface{}) string {
return "Reader1" return "Reader1"
case io.Reader: // ERROR "duplicate" case io.Reader: // ERROR "duplicate"
return "Reader2" return "Reader2"
case interface { r(); w() }: case interface {
r()
w()
}:
return "rw" return "rw"
case interface { w(); r() }: // ERROR "duplicate" case interface { // GCCGO_ERROR "duplicate"
w()
r()
}: // GC_ERROR "duplicate"
return "wr" return "wr"
} }
return "" return ""
} }
func notused(x interface{}) {
// The first t is in a different scope than the 2nd t; it cannot
// be accessed (=> declared and not used error); but it is legal
// to declare it.
switch t := 0; t := x.(type) { // ERROR "declared and not used"
case int:
_ = t // this is using the t of "t := x.(type)"
}
}
// errchk $G -e $D/$F.go
// 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.
package main
type I interface {
M()
}
func main(){
var x I
switch x.(type) {
case string: // ERROR "impossible"
println("FAIL")
}
}
...@@ -9,13 +9,10 @@ package main ...@@ -9,13 +9,10 @@ package main
import ( import (
"fmt" "fmt"
"math" "math"
"runtime"
"strings" "strings"
) )
type Error interface {
String() string
}
type ErrorTest struct { type ErrorTest struct {
name string name string
fn func() fn func()
...@@ -161,10 +158,10 @@ var errorTests = []ErrorTest{ ...@@ -161,10 +158,10 @@ var errorTests = []ErrorTest{
ErrorTest{"complex128 1/0", func() { use(e128 / d128) }, ""}, ErrorTest{"complex128 1/0", func() { use(e128 / d128) }, ""},
} }
func error(fn func()) (error string) { func error_(fn func()) (error string) {
defer func() { defer func() {
if e := recover(); e != nil { if e := recover(); e != nil {
error = e.(Error).String() error = e.(runtime.Error).Error()
} }
}() }()
fn() fn()
...@@ -199,7 +196,7 @@ func main() { ...@@ -199,7 +196,7 @@ func main() {
if t.err != "" { if t.err != "" {
continue continue
} }
err := error(t.fn) err := error_(t.fn)
switch { switch {
case t.err == "" && err == "": case t.err == "" && err == "":
// fine // fine
......
# Copyright (C) 2009 Free Software Foundation, Inc. # Copyright (C) 2009, 2011, 2012 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
...@@ -138,6 +138,7 @@ proc go-torture-execute { src } { ...@@ -138,6 +138,7 @@ proc go-torture-execute { src } {
global tool global tool
global compiler_conditional_xfail_data global compiler_conditional_xfail_data
global TORTURE_OPTIONS global TORTURE_OPTIONS
global go_compile_args
global go_execute_args global go_execute_args
# Check for alternate driver. # Check for alternate driver.
...@@ -156,6 +157,9 @@ proc go-torture-execute { src } { ...@@ -156,6 +157,9 @@ proc go-torture-execute { src } {
set executable $tmpdir/[file tail [file rootname $src].x] set executable $tmpdir/[file tail [file rootname $src].x]
regsub "(?q)$srcdir/" $src "" testcase regsub "(?q)$srcdir/" $src "" testcase
if { ! [info exists go_compile_args] } {
set go_compile_args ""
}
if { ! [info exists go_execute_args] } { if { ! [info exists go_execute_args] } {
set go_execute_args "" set go_execute_args ""
} }
...@@ -194,6 +198,9 @@ proc go-torture-execute { src } { ...@@ -194,6 +198,9 @@ proc go-torture-execute { src } {
if { $additional_flags != "" } { if { $additional_flags != "" } {
lappend options "additional_flags=$additional_flags" lappend options "additional_flags=$additional_flags"
} }
if { $go_compile_args != "" } {
lappend options "additional_flags=$go_compile_args"
}
set comp_output [go_target_compile "$src" "$executable" executable $options] set comp_output [go_target_compile "$src" "$executable" executable $options]
# See if we got something bad. # See if we got something bad.
......
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