summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/bench/shootout/threadring.c12
-rwxr-xr-xtest/bench/shootout/timing.sh157
-rw-r--r--test/cmp.go59
-rw-r--r--test/cmp6.go13
-rw-r--r--test/const1.go8
-rw-r--r--test/const5.go4
-rw-r--r--test/deferfin.go12
-rw-r--r--test/divmod.go2
-rw-r--r--test/escape2.go155
-rw-r--r--test/escape5.go8
-rw-r--r--test/fixedbugs/bug176.go2
-rw-r--r--test/fixedbugs/bug191.dir/a.go4
-rw-r--r--test/fixedbugs/bug191.dir/b.go4
-rw-r--r--test/fixedbugs/bug191.dir/main.go3
-rw-r--r--test/fixedbugs/bug191.go2
-rw-r--r--test/fixedbugs/bug191.out2
-rw-r--r--test/fixedbugs/bug385_32.go4
-rw-r--r--test/fixedbugs/bug385_64.go2
-rw-r--r--test/fixedbugs/bug462.go2
-rw-r--r--test/fixedbugs/bug476.go2
-rw-r--r--test/fixedbugs/bug480.dir/a.go17
-rw-r--r--test/fixedbugs/bug480.dir/b.go13
-rw-r--r--test/fixedbugs/bug480.go9
-rw-r--r--test/fixedbugs/bug481.go18
-rw-r--r--test/fixedbugs/bug482.go20
-rw-r--r--test/fixedbugs/bug483.go36
-rw-r--r--test/fixedbugs/bug484.go90
-rw-r--r--test/fixedbugs/bug485.go39
-rw-r--r--test/fixedbugs/issue1304.go23
-rw-r--r--test/fixedbugs/issue3705.go2
-rw-r--r--test/fixedbugs/issue4251.go6
-rw-r--r--test/fixedbugs/issue4388.go56
-rw-r--r--test/fixedbugs/issue4405.go8
-rw-r--r--test/fixedbugs/issue4429.go2
-rw-r--r--test/fixedbugs/issue4510.dir/f1.go2
-rw-r--r--test/fixedbugs/issue4517d.go2
-rw-r--r--test/fixedbugs/issue4545.go2
-rw-r--r--test/fixedbugs/issue4610.go4
-rw-r--r--test/fixedbugs/issue4618.go5
-rw-r--r--test/fixedbugs/issue4654.go44
-rw-r--r--test/fixedbugs/issue4667.go4
-rw-r--r--test/fixedbugs/issue4776.go2
-rw-r--r--test/fixedbugs/issue4813.go12
-rw-r--r--test/fixedbugs/issue4847.go2
-rw-r--r--test/fixedbugs/issue5089.go4
-rw-r--r--test/fixedbugs/issue5172.go4
-rw-r--r--test/fixedbugs/issue5358.go2
-rw-r--r--test/fixedbugs/issue5493.go5
-rw-r--r--test/fixedbugs/issue5581.go2
-rw-r--r--test/fixedbugs/issue5793.go36
-rw-r--r--test/fixedbugs/issue5957.dir/c.go10
-rw-r--r--test/fixedbugs/issue6295.dir/p0.go13
-rw-r--r--test/fixedbugs/issue6295.dir/p1.go26
-rw-r--r--test/fixedbugs/issue6295.dir/p2.go19
-rw-r--r--test/fixedbugs/issue6295.go10
-rw-r--r--test/fixedbugs/issue6402.go13
-rw-r--r--test/fixedbugs/issue6403.go14
-rw-r--r--test/fixedbugs/issue6405.go13
-rw-r--r--test/fixedbugs/issue6406.go12
-rw-r--r--test/fixedbugs/issue6500.go29
-rw-r--r--test/fixedbugs/issue6572.go21
-rw-r--r--test/fixedbugs/issue6789.dir/a.go14
-rw-r--r--test/fixedbugs/issue6789.dir/b.go12
-rw-r--r--test/fixedbugs/issue6789.go10
-rw-r--r--test/fixedbugs/issue6847.go85
-rw-r--r--test/fixedbugs/issue6889.go103
-rw-r--r--test/fixedbugs/issue6899.go13
-rw-r--r--test/fixedbugs/issue6899.out1
-rw-r--r--test/fixedbugs/issue6902.go21
-rw-r--r--test/fixedbugs/issue6964.go11
-rw-r--r--test/fixedbugs/issue7023.dir/a.go10
-rw-r--r--test/fixedbugs/issue7023.dir/b.go11
-rw-r--r--test/fixedbugs/issue7023.go10
-rw-r--r--test/fixedbugs/issue7044.go43
-rw-r--r--test/fixedbugs/issue7050.go19
-rw-r--r--test/fixedbugs/issue7083.go22
-rw-r--r--test/fixedbugs/issue7129.go21
-rw-r--r--test/fixedbugs/issue7150.go17
-rw-r--r--test/fixedbugs/issue7153.go11
-rw-r--r--test/fixedbugs/issue7214.go30
-rw-r--r--test/fixedbugs/issue7223.go20
-rw-r--r--test/fixedbugs/issue7272.go48
-rw-r--r--test/fixedbugs/issue7310.go15
-rw-r--r--test/fixedbugs/issue7316.go37
-rw-r--r--test/fixedbugs/issue7346.go14
-rw-r--r--test/fixedbugs/issue7366.go21
-rw-r--r--test/fixedbugs/issue7405.go51
-rw-r--r--test/fixedbugs/issue7419.go25
-rw-r--r--test/fixedbugs/issue7525.go19
-rw-r--r--test/fixedbugs/issue7538a.go15
-rw-r--r--test/fixedbugs/issue7538b.go13
-rw-r--r--test/fixedbugs/issue7547.go17
-rw-r--r--test/fixedbugs/issue7550.go27
-rw-r--r--test/fixedbugs/issue7590.go21
-rw-r--r--test/fixedbugs/issue7648.dir/a.go11
-rw-r--r--test/fixedbugs/issue7648.dir/b.go11
-rw-r--r--test/fixedbugs/issue7648.go9
-rw-r--r--test/fixedbugs/issue7675.go24
-rw-r--r--test/fixedbugs/issue7742.go18
-rw-r--r--test/fixedbugs/issue7794.go12
-rw-r--r--test/fixedbugs/issue7863.go60
-rw-r--r--test/fixedbugs/issue7867.go43
-rw-r--r--test/fixedbugs/issue7884.go15
-rw-r--r--test/fixedbugs/issue7944.go40
-rw-r--r--test/fixedbugs/issue7995.go25
-rw-r--r--test/fixedbugs/issue7995b.dir/x1.go16
-rw-r--r--test/fixedbugs/issue7995b.dir/x2.go10
-rw-r--r--test/fixedbugs/issue7995b.go9
-rw-r--r--test/fixedbugs/issue7996.go14
-rw-r--r--test/fixedbugs/issue7997.go53
-rw-r--r--test/fixedbugs/issue7998.go23
-rw-r--r--test/fixedbugs/issue8004.go59
-rw-r--r--test/fixedbugs/issue8011.go18
-rw-r--r--test/fixedbugs/issue8028.go27
-rw-r--r--test/fixedbugs/issue8036.go45
-rw-r--r--test/fixedbugs/issue8039.go23
-rw-r--r--test/fixedbugs/issue8047.go29
-rw-r--r--test/fixedbugs/issue8047b.go22
-rw-r--r--test/fixedbugs/issue8048.go107
-rw-r--r--test/fixedbugs/issue8073.go15
-rw-r--r--test/fixedbugs/issue8076.go17
-rw-r--r--test/fixedbugs/issue8132.go32
-rw-r--r--test/fixedbugs/issue8139.go50
-rw-r--r--test/fixedbugs/issue8155.go48
-rw-r--r--test/fixedbugs/issue8158.go41
-rw-r--r--test/float_lit2.go164
-rw-r--r--test/float_lit3.go48
-rw-r--r--test/funcdup.go24
-rw-r--r--test/funcdup2.go12
-rw-r--r--test/gc2.go4
-rw-r--r--test/gcstring.go48
-rw-r--r--test/import1.go2
-rw-r--r--test/import4.dir/empty.go2
-rw-r--r--test/import4.dir/import4.go4
-rw-r--r--test/live.go624
-rw-r--r--test/live1.go46
-rw-r--r--test/live2.go39
-rw-r--r--test/method4.dir/prog.go9
-rw-r--r--test/nilptr3.go102
-rw-r--r--test/nilptr4.go24
-rw-r--r--test/nosplit.go314
-rw-r--r--test/reorder2.go169
-rwxr-xr-xtest/run2
-rw-r--r--test/run.go139
-rw-r--r--test/sigchld.go2
-rw-r--r--test/slice3err.go56
-rw-r--r--test/string_lit.go5
-rw-r--r--test/syntax/semi1.go2
-rw-r--r--test/syntax/semi2.go2
-rw-r--r--test/syntax/semi3.go2
-rw-r--r--test/syntax/semi4.go2
-rw-r--r--test/tinyfin.go62
-rw-r--r--test/typecheck.go4
153 files changed, 4450 insertions, 304 deletions
diff --git a/test/bench/shootout/threadring.c b/test/bench/shootout/threadring.c
index a518134ba..606db71dc 100644
--- a/test/bench/shootout/threadring.c
+++ b/test/bench/shootout/threadring.c
@@ -41,8 +41,12 @@ POSSIBILITY OF SUCH DAMAGE.
#include <string.h>
#include <limits.h>
-#define THREADS (503)
+// PTHREAD_STACK_MIN undeclared on mingw
+#ifndef PTHREAD_STACK_MIN
+#define PTHREAD_STACK_MIN 65535
+#endif
+#define THREADS (503)
struct stack {
char x[PTHREAD_STACK_MIN];
@@ -94,7 +98,13 @@ int main(int argc, char **argv)
pthread_mutex_init(mutex + i, NULL);
pthread_mutex_lock(mutex + i);
+#if defined(__MINGW32__) || defined(__MINGW64__)
+ pthread_attr_setstackaddr(&stack_attr, &stacks[i]);
+ pthread_attr_setstacksize(&stack_attr, sizeof(struct stack));
+#else
pthread_attr_setstack(&stack_attr, &stacks[i], sizeof(struct stack));
+#endif
+
pthread_create(&cthread, &stack_attr, thread, (void*)(uintptr_t)i);
}
diff --git a/test/bench/shootout/timing.sh b/test/bench/shootout/timing.sh
index 2db895c26..a06c326c3 100755
--- a/test/bench/shootout/timing.sh
+++ b/test/bench/shootout/timing.sh
@@ -18,6 +18,33 @@ case "$O" in
gccm=-m64;;
esac
+EXE="out"
+havepcre=true
+haveglib=true
+havegmp=true
+case "$(uname)" in
+*MINGW* | *WIN32* | *CYGWIN*)
+ havepcre=false
+ haveglib=false
+ havegmp=false
+ if which pkg-config >/dev/null 2>&1; then
+ if pkg-config --cflags libpcre >/dev/null 2>&1
+ then
+ echo "havepcre"
+ havepcre=true
+ fi
+ if pkg-config --cflags glib-2.0 >/dev/null 2>&1
+ then
+ haveglib=true
+ fi
+ if pkg-config --cflags gmp >/dev/null 2>&1
+ then
+ havegmp=true
+ fi
+ fi
+ EXE=exe;;
+esac
+
PATH=.:$PATH
havegccgo=false
@@ -34,11 +61,11 @@ X-test)
esac
gc() {
- $GC $1.go; $LD $1.$O
+ $GC $1.go; $LD -o $O.$EXE $1.$O
}
gc_B() {
- $GC -B $1.go; $LD $1.$O
+ $GC -B $1.go; $LD -o $O.$EXE $1.$O
}
runonly() {
@@ -86,122 +113,126 @@ run() {
fasta() {
runonly echo 'fasta -n 25000000'
- run "gcc $gccm -O2 fasta.c" a.out 25000000
- run 'gccgo -O2 fasta.go' a.out -n 25000000 #commented out until WriteString is in bufio
- run 'gc fasta' $O.out -n 25000000
- run 'gc_B fasta' $O.out -n 25000000
+ run "gcc $gccm -O2 fasta.c" a.$EXE 25000000
+ run 'gccgo -O2 fasta.go' a.$EXE -n 25000000 #commented out until WriteString is in bufio
+ run 'gc fasta' $O.$EXE -n 25000000
+ run 'gc_B fasta' $O.$EXE -n 25000000
}
revcomp() {
runonly gcc -O2 fasta.c
- runonly a.out 25000000 > x
+ runonly a.$EXE 25000000 > x
runonly echo 'reverse-complement < output-of-fasta-25000000'
- run "gcc $gccm -O2 reverse-complement.c" a.out < x
- run 'gccgo -O2 reverse-complement.go' a.out < x
- run 'gc reverse-complement' $O.out < x
- run 'gc_B reverse-complement' $O.out < x
+ run "gcc $gccm -O2 reverse-complement.c" a.$EXE < x
+ run 'gccgo -O2 reverse-complement.go' a.$EXE < x
+ run 'gc reverse-complement' $O.$EXE < x
+ run 'gc_B reverse-complement' $O.$EXE < x
rm x
}
nbody() {
runonly echo 'nbody -n 50000000'
- run "gcc $gccm -O2 nbody.c -lm" a.out 50000000
- run 'gccgo -O2 nbody.go' a.out -n 50000000
- run 'gc nbody' $O.out -n 50000000
- run 'gc_B nbody' $O.out -n 50000000
+ run "gcc $gccm -O2 nbody.c -lm" a.$EXE 50000000
+ run 'gccgo -O2 nbody.go' a.$EXE -n 50000000
+ run 'gc nbody' $O.$EXE -n 50000000
+ run 'gc_B nbody' $O.$EXE -n 50000000
}
binarytree() {
runonly echo 'binary-tree 15 # too slow to use 20'
- run "gcc $gccm -O2 binary-tree.c -lm" a.out 15
- run 'gccgo -O2 binary-tree.go' a.out -n 15
- run 'gccgo -O2 binary-tree-freelist.go' a.out -n 15
- run 'gc binary-tree' $O.out -n 15
- run 'gc binary-tree-freelist' $O.out -n 15
+ run "gcc $gccm -O2 binary-tree.c -lm" a.$EXE 15
+ run 'gccgo -O2 binary-tree.go' a.$EXE -n 15
+ run 'gccgo -O2 binary-tree-freelist.go' a.$EXE -n 15
+ run 'gc binary-tree' $O.$EXE -n 15
+ run 'gc binary-tree-freelist' $O.$EXE -n 15
}
fannkuch() {
runonly echo 'fannkuch 12'
- run "gcc $gccm -O2 fannkuch.c" a.out 12
- run 'gccgo -O2 fannkuch.go' a.out -n 12
- run 'gccgo -O2 fannkuch-parallel.go' a.out -n 12
- run 'gc fannkuch' $O.out -n 12
- run 'gc fannkuch-parallel' $O.out -n 12
- run 'gc_B fannkuch' $O.out -n 12
+ run "gcc $gccm -O2 fannkuch.c" a.$EXE 12
+ run 'gccgo -O2 fannkuch.go' a.$EXE -n 12
+ run 'gccgo -O2 fannkuch-parallel.go' a.$EXE -n 12
+ run 'gc fannkuch' $O.$EXE -n 12
+ run 'gc fannkuch-parallel' $O.$EXE -n 12
+ run 'gc_B fannkuch' $O.$EXE -n 12
}
regexdna() {
runonly gcc -O2 fasta.c
- runonly a.out 100000 > x
+ runonly a.$EXE 100000 > x
runonly echo 'regex-dna 100000'
- run "gcc $gccm -O2 regex-dna.c -lpcre" a.out <x
- run 'gccgo -O2 regex-dna.go' a.out <x
- run 'gccgo -O2 regex-dna-parallel.go' a.out <x
- run 'gc regex-dna' $O.out <x
- run 'gc regex-dna-parallel' $O.out <x
- run 'gc_B regex-dna' $O.out <x
+ if $havepcre; then
+ run "gcc $gccm -O2 regex-dna.c $(pkg-config libpcre --cflags --libs)" a.$EXE <x
+ fi
+ run 'gccgo -O2 regex-dna.go' a.$EXE <x
+ run 'gccgo -O2 regex-dna-parallel.go' a.$EXE <x
+ run 'gc regex-dna' $O.$EXE <x
+ run 'gc regex-dna-parallel' $O.$EXE <x
+ run 'gc_B regex-dna' $O.$EXE <x
rm x
}
spectralnorm() {
runonly echo 'spectral-norm 5500'
- run "gcc $gccm -O2 spectral-norm.c -lm" a.out 5500
- run 'gccgo -O2 spectral-norm.go' a.out -n 5500
- run 'gc spectral-norm' $O.out -n 5500
- run 'gc_B spectral-norm' $O.out -n 5500
+ run "gcc $gccm -O2 spectral-norm.c -lm" a.$EXE 5500
+ run 'gccgo -O2 spectral-norm.go' a.$EXE -n 5500
+ run 'gc spectral-norm' $O.$EXE -n 5500
+ run 'gc_B spectral-norm' $O.$EXE -n 5500
}
knucleotide() {
runonly gcc -O2 fasta.c
- runonly a.out 1000000 > x # should be using 25000000
+ runonly a.$EXE 1000000 > x # should be using 25000000
runonly echo 'k-nucleotide 1000000'
- if [ $mode = run ]; then
- run "gcc -O2 k-nucleotide.c $(pkg-config glib-2.0 --cflags --libs)" a.out <x
+ if [ $mode = run ] && $haveglib; then
+ run "gcc -O2 k-nucleotide.c $(pkg-config glib-2.0 --cflags --libs)" a.$EXE <x
fi
- run 'gccgo -O2 k-nucleotide.go' a.out <x
- run 'gccgo -O2 k-nucleotide-parallel.go' a.out <x
- run 'gc k-nucleotide' $O.out <x
- run 'gc k-nucleotide-parallel' $O.out <x
- run 'gc_B k-nucleotide' $O.out <x
+ run 'gccgo -O2 k-nucleotide.go' a.$EXE <x
+ run 'gccgo -O2 k-nucleotide-parallel.go' a.$EXE <x
+ run 'gc k-nucleotide' $O.$EXE <x
+ run 'gc k-nucleotide-parallel' $O.$EXE <x
+ run 'gc_B k-nucleotide' $O.$EXE <x
rm x
}
mandelbrot() {
runonly echo 'mandelbrot 16000'
- run "gcc $gccm -O2 mandelbrot.c" a.out 16000
- run 'gccgo -O2 mandelbrot.go' a.out -n 16000
- run 'gc mandelbrot' $O.out -n 16000
- run 'gc_B mandelbrot' $O.out -n 16000
+ run "gcc $gccm -O2 mandelbrot.c" a.$EXE 16000
+ run 'gccgo -O2 mandelbrot.go' a.$EXE -n 16000
+ run 'gc mandelbrot' $O.$EXE -n 16000
+ run 'gc_B mandelbrot' $O.$EXE -n 16000
}
meteor() {
runonly echo 'meteor 2098'
- run "gcc $gccm -O2 meteor-contest.c" a.out 2098
- run 'gccgo -O2 meteor-contest.go' a.out -n 2098
- run 'gc meteor-contest' $O.out -n 2098
- run 'gc_B meteor-contest' $O.out -n 2098
+ run "gcc $gccm -O2 meteor-contest.c" a.$EXE 2098
+ run 'gccgo -O2 meteor-contest.go' a.$EXE -n 2098
+ run 'gc meteor-contest' $O.$EXE -n 2098
+ run 'gc_B meteor-contest' $O.$EXE -n 2098
}
pidigits() {
runonly echo 'pidigits 10000'
- run "gcc $gccm -O2 pidigits.c -lgmp" a.out 10000
- run 'gccgo -O2 pidigits.go' a.out -n 10000
- run 'gc pidigits' $O.out -n 10000
- run 'gc_B pidigits' $O.out -n 10000
+ if $havegmp; then
+ run "gcc $gccm -O2 pidigits.c -lgmp" a.$EXE 10000
+ fi
+ run 'gccgo -O2 pidigits.go' a.$EXE -n 10000
+ run 'gc pidigits' $O.$EXE -n 10000
+ run 'gc_B pidigits' $O.$EXE -n 10000
}
threadring() {
runonly echo 'threadring 50000000'
- run "gcc $gccm -O2 threadring.c -lpthread" a.out 50000000
- run 'gccgo -O2 threadring.go' a.out -n 50000000
- run 'gc threadring' $O.out -n 50000000
+ run "gcc $gccm -O2 threadring.c -lpthread" a.$EXE 50000000
+ run 'gccgo -O2 threadring.go' a.$EXE -n 50000000
+ run 'gc threadring' $O.$EXE -n 50000000
}
chameneos() {
runonly echo 'chameneos 6000000'
- run "gcc $gccm -O2 chameneosredux.c -lpthread" a.out 6000000
- run 'gccgo -O2 chameneosredux.go' a.out 6000000
- run 'gc chameneosredux' $O.out 6000000
+ run "gcc $gccm -O2 chameneosredux.c -lpthread" a.$EXE 6000000
+ run 'gccgo -O2 chameneosredux.go' a.$EXE 6000000
+ run 'gc chameneosredux' $O.$EXE 6000000
}
case $# in
diff --git a/test/cmp.go b/test/cmp.go
index 73de502f3..80d1bf699 100644
--- a/test/cmp.go
+++ b/test/cmp.go
@@ -35,6 +35,10 @@ func istrue(b bool) {
type T *int
+type X int
+
+func (X) x() {}
+
func main() {
var a []int
var b map[string]int
@@ -129,6 +133,44 @@ func main() {
panic("bad m[c]")
}
+ // interface comparisons (issue 7207)
+ {
+ type I1 interface {
+ x()
+ }
+ type I2 interface {
+ x()
+ }
+ a1 := I1(X(0))
+ b1 := I1(X(1))
+ a2 := I2(X(0))
+ b2 := I2(X(1))
+ a3 := I1(a2)
+ a4 := I2(a1)
+ var e interface{} = X(0)
+ a5 := e.(I1)
+ a6 := e.(I2)
+ isfalse(a1 == b1)
+ isfalse(a1 == b2)
+ isfalse(a2 == b1)
+ isfalse(a2 == b2)
+ istrue(a1 == a2)
+ istrue(a1 == a3)
+ istrue(a1 == a4)
+ istrue(a1 == a5)
+ istrue(a1 == a6)
+ istrue(a2 == a3)
+ istrue(a2 == a4)
+ istrue(a2 == a5)
+ istrue(a2 == a6)
+ istrue(a3 == a4)
+ istrue(a3 == a5)
+ istrue(a3 == a6)
+ istrue(a4 == a5)
+ istrue(a4 == a6)
+ istrue(a5 == a6)
+ }
+
// non-interface comparisons
{
c := make(chan int)
@@ -387,6 +429,23 @@ func main() {
isfalse(iz != x)
}
+ // named booleans
+ {
+ type mybool bool
+ var b mybool
+
+ type T struct{ data [20]byte }
+ var x, y T
+ b = x == y
+ istrue(x == y)
+ istrue(bool(b))
+
+ m := make(map[string][10]interface{})
+ b = m["x"] == m["y"]
+ istrue(m["x"] == m["y"])
+ istrue(bool(b))
+ }
+
shouldPanic(p1)
shouldPanic(p2)
shouldPanic(p3)
diff --git a/test/cmp6.go b/test/cmp6.go
index 839c274bc..7cf76044e 100644
--- a/test/cmp6.go
+++ b/test/cmp6.go
@@ -18,7 +18,10 @@ type T3 struct{ z []int }
var t3 T3
-type T4 struct { _ []int; a float64 }
+type T4 struct {
+ _ []int
+ a float64
+}
var t4 T4
@@ -51,6 +54,14 @@ func main() {
use(p3 == p1)
use(p3 == p2)
+ // Arrays are comparable if and only if their element type is comparable.
+ var a1 [1]int
+ var a2 [1]func()
+ var a3 [0]func()
+ use(a1 == a1)
+ use(a2 == a2) // ERROR "invalid operation|invalid comparison"
+ use(a3 == a3) // ERROR "invalid operation|invalid comparison"
+
// Comparison of structs should have a good message
use(t3 == t3) // ERROR "struct|expected"
use(t4 == t4) // ERROR "cannot be compared|non-comparable"
diff --git a/test/const1.go b/test/const1.go
index a170ce9e7..58bddee7e 100644
--- a/test/const1.go
+++ b/test/const1.go
@@ -88,7 +88,7 @@ func main() {
}
const ptr = nil // ERROR "const.*nil"
-const _ = string([]byte(nil)) // ERROR "is not a constant"
-const _ = uintptr(unsafe.Pointer((*int)(nil))) // ERROR "is not a constant"
-const _ = unsafe.Pointer((*int)(nil)) // ERROR "cannot be nil"
-const _ = (*int)(nil) // ERROR "cannot be nil"
+const _ = string([]byte(nil)) // ERROR "is not a? ?constant"
+const _ = uintptr(unsafe.Pointer((*int)(nil))) // ERROR "is not a? ?constant"
+const _ = unsafe.Pointer((*int)(nil)) // ERROR "cannot be nil|invalid constant type"
+const _ = (*int)(nil) // ERROR "cannot be nil|invalid constant type"
diff --git a/test/const5.go b/test/const5.go
index 87fe33a38..60b4d0d12 100644
--- a/test/const5.go
+++ b/test/const5.go
@@ -18,6 +18,7 @@ var s [][30]int
func f() *[40]int
var c chan *[50]int
+var z complex128
const (
n1 = len(b.a)
@@ -29,5 +30,8 @@ const (
n6 = cap(f()) // ERROR "is not a constant|is not constant"
n7 = cap(<-c) // ERROR "is not a constant|is not constant"
+ n8 = real(z) // ERROR "is not a constant|is not constant"
+ n9 = len([4]float64{real(z)}) // ERROR "is not a constant|is not constant"
+
)
diff --git a/test/deferfin.go b/test/deferfin.go
index f9a74eba9..80372916d 100644
--- a/test/deferfin.go
+++ b/test/deferfin.go
@@ -23,6 +23,10 @@ func main() {
if runtime.GOARCH != "amd64" {
return
}
+ // Likewise for gccgo.
+ if runtime.Compiler == "gccgo" {
+ return
+ }
N := 10
count := int32(N)
var wg sync.WaitGroup
@@ -30,17 +34,17 @@ func main() {
for i := 0; i < N; i++ {
go func() {
defer wg.Done()
- v := new(int)
+ v := new(string)
f := func() {
- if *v != 0 {
+ if *v != "" {
panic("oops")
}
}
- if *v != 0 {
+ if *v != "" {
// let the compiler think f escapes
sink = f
}
- runtime.SetFinalizer(v, func(p *int) {
+ runtime.SetFinalizer(v, func(p *string) {
atomic.AddInt32(&count, -1)
})
defer f()
diff --git a/test/divmod.go b/test/divmod.go
index 49fed0222..ad632bc83 100644
--- a/test/divmod.go
+++ b/test/divmod.go
@@ -6,7 +6,7 @@
// Test division of variables. Generate many test cases,
// compute correct answer using shift and subtract,
-// and then compare against results from divison and
+// and then compare against results from division and
// modulus operators.
//
// Primarily useful for testing software div/mod.
diff --git a/test/escape2.go b/test/escape2.go
index be89c2d84..28251aa98 100644
--- a/test/escape2.go
+++ b/test/escape2.go
@@ -80,7 +80,7 @@ func foo12(yyy **int) { // ERROR "leaking param: yyy"
xxx = yyy
}
-// Must treat yyy as leaking because *yyy leaks, and the escape analysis
+// Must treat yyy as leaking because *yyy leaks, and the escape analysis
// summaries in exported metadata do not distinguish these two cases.
func foo13(yyy **int) { // ERROR "leaking param: yyy"
*xxx = *yyy
@@ -135,7 +135,7 @@ 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"
+func (b *Bar) AlsoNoLeak() *int { // ERROR "leaking param b content to result ~r0"
return b.ii
}
@@ -149,7 +149,7 @@ func (b Bar) LeaksToo() *int { // ERROR "leaking param: b"
return b.ii
}
-func (b *Bar) LeaksABit() *int { // ERROR "b does not escape"
+func (b *Bar) LeaksABit() *int { // ERROR "leaking param b content to result ~r0"
v := 0 // ERROR "moved to heap: v"
b.ii = &v // ERROR "&v escapes"
return b.ii
@@ -182,7 +182,7 @@ 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"
+func (b *Bar2) AlsoNoLeak() []int { // ERROR "leaking param b content to result ~r0"
return b.ii[0:1]
}
@@ -1294,15 +1294,15 @@ func F4(x []byte)
func G() {
var buf1 [10]byte
F1(buf1[:]) // ERROR "buf1 does not escape"
-
+
var buf2 [10]byte // ERROR "moved to heap: buf2"
- F2(buf2[:]) // ERROR "buf2 escapes to heap"
+ F2(buf2[:]) // ERROR "buf2 escapes to heap"
var buf3 [10]byte
F3(buf3[:]) // ERROR "buf3 does not escape"
-
+
var buf4 [10]byte // ERROR "moved to heap: buf4"
- F4(buf4[:]) // ERROR "buf4 escapes to heap"
+ F4(buf4[:]) // ERROR "buf4 escapes to heap"
}
type Tm struct {
@@ -1314,9 +1314,9 @@ func (t *Tm) M() { // ERROR "t does not escape"
func foo141() {
var f func()
-
+
t := new(Tm) // ERROR "escapes to heap"
- f = t.M // ERROR "t.M does not escape"
+ f = t.M // ERROR "t.M does not escape"
_ = f
}
@@ -1324,7 +1324,7 @@ var gf func()
func foo142() {
t := new(Tm) // ERROR "escapes to heap"
- gf = t.M // ERROR "t.M escapes to heap"
+ gf = t.M // ERROR "t.M escapes to heap"
}
// issue 3888.
@@ -1357,3 +1357,136 @@ func foo144() {
//go:noescape
func foo144b(*int)
+
+// issue 7313: for loop init should not be treated as "in loop"
+
+type List struct {
+ Next *List
+}
+
+func foo145(l List) { // ERROR "l does not escape"
+ var p *List
+ for p = &l; p.Next != nil; p = p.Next { // ERROR "&l does not escape"
+ }
+}
+
+func foo146(l List) { // ERROR "l does not escape"
+ var p *List
+ p = &l // ERROR "&l does not escape"
+ for ; p.Next != nil; p = p.Next {
+ }
+}
+
+func foo147(l List) { // ERROR "l does not escape"
+ var p *List
+ p = &l // ERROR "&l does not escape"
+ for p.Next != nil {
+ p = p.Next
+ }
+}
+
+func foo148(l List) { // ERROR " l does not escape"
+ for p := &l; p.Next != nil; p = p.Next { // ERROR "&l does not escape"
+ }
+}
+
+// related: address of variable should have depth of variable, not of loop
+
+func foo149(l List) { // ERROR " l does not escape"
+ var p *List
+ for {
+ for p = &l; p.Next != nil; p = p.Next { // ERROR "&l does not escape"
+ }
+ }
+}
+
+// issue 7934: missed ... if element type had no pointers
+
+var save150 []byte
+
+func foo150(x ...byte) { // ERROR "leaking param: x"
+ save150 = x
+}
+
+func bar150() {
+ foo150(1, 2, 3) // ERROR "[.][.][.] argument escapes to heap"
+}
+
+// issue 7931: bad handling of slice of array
+
+var save151 *int
+
+func foo151(x *int) { // ERROR "leaking param: x"
+ save151 = x
+}
+
+func bar151() {
+ var a [64]int // ERROR "moved to heap: a"
+ a[4] = 101
+ foo151(&(&a)[4:8][0]) // ERROR "&\(&a\)\[4:8\]\[0\] escapes to heap" "&a escapes to heap"
+}
+
+func bar151b() {
+ var a [10]int // ERROR "moved to heap: a"
+ b := a[:] // ERROR "a escapes to heap"
+ foo151(&b[4:8][0]) // ERROR "&b\[4:8\]\[0\] escapes to heap"
+}
+
+func bar151c() {
+ var a [64]int // ERROR "moved to heap: a"
+ a[4] = 101
+ foo151(&(&a)[4:8:8][0]) // ERROR "&\(&a\)\[4:8:8\]\[0\] escapes to heap" "&a escapes to heap"
+}
+
+func bar151d() {
+ var a [10]int // ERROR "moved to heap: a"
+ b := a[:] // ERROR "a escapes to heap"
+ foo151(&b[4:8:8][0]) // ERROR "&b\[4:8:8\]\[0\] escapes to heap"
+}
+
+// issue 8120
+
+type U struct {
+ s *string
+}
+
+func (u *U) String() *string { // ERROR "leaking param u content to result ~r0"
+ return u.s
+}
+
+type V struct {
+ s *string
+}
+
+func NewV(u U) *V { // ERROR "leaking param: u"
+ return &V{u.String()} // ERROR "&V literal escapes to heap" "u does not escape"
+}
+
+func foo152() {
+ a := "a" // ERROR "moved to heap: a"
+ u := U{&a} // ERROR "&a escapes to heap"
+ v := NewV(u)
+ println(v)
+}
+
+// issue 8176 - &x in type switch body not marked as escaping
+
+func foo153(v interface{}) *int { // ERROR "leaking param: v"
+ switch x := v.(type) {
+ case int: // ERROR "moved to heap: x"
+ return &x // ERROR "&x escapes to heap"
+ }
+ panic(0)
+}
+
+// issue 8185 - &result escaping into result
+
+func f() (x int, y *int) { // ERROR "moved to heap: x"
+ y = &x // ERROR "&x escapes to heap"
+ return
+}
+
+func g() (x interface{}) { // ERROR "moved to heap: x"
+ x = &x // ERROR "&x escapes to heap"
+ return
+}
diff --git a/test/escape5.go b/test/escape5.go
index c9646872d..a33daeee1 100644
--- a/test/escape5.go
+++ b/test/escape5.go
@@ -17,19 +17,19 @@ func leaktoret(p *int) *int { // ERROR "leaking param: p to result"
return p
}
-func leaktoret2(p *int) (*int, *int) { // ERROR "leaking param: p to result .anon1" "leaking param: p to result .anon2"
+func leaktoret2(p *int) (*int, *int) { // ERROR "leaking param: p to result ~r1" "leaking param: p to result ~r2"
return p, p
}
-func leaktoret22(p, q *int) (*int, *int) { // ERROR "leaking param: p to result .anon2" "leaking param: q to result .anon3"
+func leaktoret22(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r2" "leaking param: q to result ~r3"
return p, q
}
-func leaktoret22b(p, q *int) (*int, *int) { // ERROR "leaking param: p to result .anon3" "leaking param: q to result .anon2"
+func leaktoret22b(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r3" "leaking param: q to result ~r2"
return leaktoret22(q, p)
}
-func leaktoret22c(p, q *int) (*int, *int) { // ERROR "leaking param: p to result .anon3" "leaking param: q to result .anon2"
+func leaktoret22c(p, q *int) (*int, *int) { // ERROR "leaking param: p to result ~r3" "leaking param: q to result ~r2"
r, s := leaktoret22(q, p)
return r, s
}
diff --git a/test/fixedbugs/bug176.go b/test/fixedbugs/bug176.go
index 82f8dba0a..ea3a90974 100644
--- a/test/fixedbugs/bug176.go
+++ b/test/fixedbugs/bug176.go
@@ -9,6 +9,6 @@ package main
var x int
var a = []int{ x: 1} // ERROR "constant"
-var b = [...]int{ x : 1} // ERROR "constant"
+var b = [...]int{x: 1}
var c = map[int]int{ x: 1}
diff --git a/test/fixedbugs/bug191.dir/a.go b/test/fixedbugs/bug191.dir/a.go
index b87ad6f4f..139a8a3a2 100644
--- a/test/fixedbugs/bug191.dir/a.go
+++ b/test/fixedbugs/bug191.dir/a.go
@@ -4,8 +4,10 @@
package a
+var A int
+
func init() {
- println("a");
+ A = 1
}
type T int;
diff --git a/test/fixedbugs/bug191.dir/b.go b/test/fixedbugs/bug191.dir/b.go
index 3e780ac0d..36770f6fc 100644
--- a/test/fixedbugs/bug191.dir/b.go
+++ b/test/fixedbugs/bug191.dir/b.go
@@ -4,8 +4,10 @@
package b
+var B int
+
func init() {
- println("b");
+ B = 2
}
type V int;
diff --git a/test/fixedbugs/bug191.dir/main.go b/test/fixedbugs/bug191.dir/main.go
index 995134ccf..2d24dd12d 100644
--- a/test/fixedbugs/bug191.dir/main.go
+++ b/test/fixedbugs/bug191.dir/main.go
@@ -11,4 +11,7 @@ var _ T
var _ V
func main() {
+ if A != 1 || B != 2 {
+ panic("wrong vars")
+ }
}
diff --git a/test/fixedbugs/bug191.go b/test/fixedbugs/bug191.go
index acb4796b3..248e23edf 100644
--- a/test/fixedbugs/bug191.go
+++ b/test/fixedbugs/bug191.go
@@ -1,4 +1,4 @@
-// rundircmpout
+// rundir
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
diff --git a/test/fixedbugs/bug191.out b/test/fixedbugs/bug191.out
deleted file mode 100644
index 0e1677a97..000000000
--- a/test/fixedbugs/bug191.out
+++ /dev/null
@@ -1,2 +0,0 @@
-b
-a
diff --git a/test/fixedbugs/bug385_32.go b/test/fixedbugs/bug385_32.go
index 724ed9326..daf2a083c 100644
--- a/test/fixedbugs/bug385_32.go
+++ b/test/fixedbugs/bug385_32.go
@@ -1,4 +1,4 @@
-// +build 386 arm
+// +build 386 amd64p32 arm
// errorcheck
// Copyright 2011 The Go Authors. All rights reserved.
@@ -9,7 +9,7 @@
package main
func main() {
- var arr [1000200030]int // ERROR "type .* too large"
+ var arr [1000200030]int // GC_ERROR "type .* too large"
arr_bkup := arr
_ = arr_bkup
}
diff --git a/test/fixedbugs/bug385_64.go b/test/fixedbugs/bug385_64.go
index aef03c389..6789c0abf 100644
--- a/test/fixedbugs/bug385_64.go
+++ b/test/fixedbugs/bug385_64.go
@@ -12,7 +12,7 @@ package main
var z [10<<20]byte
-func main() { // ERROR "stack frame too large"
+func main() { // GC_ERROR "stack frame too large"
// seq 1 206 | sed 's/.*/ var x& [10<<20]byte; z = x&/'
var x1 [10<<20]byte; z = x1
var x2 [10<<20]byte; z = x2
diff --git a/test/fixedbugs/bug462.go b/test/fixedbugs/bug462.go
index 6434255c8..1a23ad064 100644
--- a/test/fixedbugs/bug462.go
+++ b/test/fixedbugs/bug462.go
@@ -14,6 +14,6 @@ type T struct {
func main() {
_ = T {
- os.File: 1, // ERROR "unknown T field"
+ os.File: 1, // ERROR "unknown T? ?field"
}
}
diff --git a/test/fixedbugs/bug476.go b/test/fixedbugs/bug476.go
index 4ea217404..563fd9156 100644
--- a/test/fixedbugs/bug476.go
+++ b/test/fixedbugs/bug476.go
@@ -5,7 +5,7 @@
// license that can be found in the LICENSE file.
// Logical operation on named boolean type returns the same type,
-// supporting an implicit convertion to an interface type. This used
+// supporting an implicit conversion to an interface type. This used
// to crash gccgo.
package p
diff --git a/test/fixedbugs/bug480.dir/a.go b/test/fixedbugs/bug480.dir/a.go
new file mode 100644
index 000000000..6dff51586
--- /dev/null
+++ b/test/fixedbugs/bug480.dir/a.go
@@ -0,0 +1,17 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+type S interface{
+ F() T
+}
+
+type T struct {
+ S
+}
+
+type U struct {
+ error
+}
diff --git a/test/fixedbugs/bug480.dir/b.go b/test/fixedbugs/bug480.dir/b.go
new file mode 100644
index 000000000..620736540
--- /dev/null
+++ b/test/fixedbugs/bug480.dir/b.go
@@ -0,0 +1,13 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package b
+
+import "./a"
+
+var t a.T
+
+func F() error {
+ return a.U{}
+}
diff --git a/test/fixedbugs/bug480.go b/test/fixedbugs/bug480.go
new file mode 100644
index 000000000..5b44af430
--- /dev/null
+++ b/test/fixedbugs/bug480.go
@@ -0,0 +1,9 @@
+// compiledir
+
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Gccgo mishandled an import of a forward declared type.
+
+package ignored
diff --git a/test/fixedbugs/bug481.go b/test/fixedbugs/bug481.go
new file mode 100644
index 000000000..d0922a5a4
--- /dev/null
+++ b/test/fixedbugs/bug481.go
@@ -0,0 +1,18 @@
+// compile
+
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Returning an index into a conversion from string to slice caused a
+// compilation error when using gccgo.
+
+package p
+
+func F1(s string) byte {
+ return []byte(s)[0]
+}
+
+func F2(s string) rune {
+ return []rune(s)[0]
+}
diff --git a/test/fixedbugs/bug482.go b/test/fixedbugs/bug482.go
new file mode 100644
index 000000000..10c48287d
--- /dev/null
+++ b/test/fixedbugs/bug482.go
@@ -0,0 +1,20 @@
+// compile
+
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Using the same name for a field in a composite literal and for a
+// global variable that depends on the variable being initialized
+// caused gccgo to erroneously report "variable initializer refers to
+// itself".
+
+package p
+
+type S struct {
+ F int
+}
+
+var V = S{F: 1}
+
+var F = V.F
diff --git a/test/fixedbugs/bug483.go b/test/fixedbugs/bug483.go
new file mode 100644
index 000000000..2372e89a7
--- /dev/null
+++ b/test/fixedbugs/bug483.go
@@ -0,0 +1,36 @@
+// run
+
+// Copyright 2014 The Go 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 for a garbage collection bug involving not
+// marking x as having its address taken by &x[0]
+// when x is an array value.
+
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "runtime"
+)
+
+func main() {
+ var x = [4]struct{ x, y interface{} }{
+ {"a", "b"},
+ {"c", "d"},
+ {"e", "f"},
+ {"g", "h"},
+ }
+
+ var buf bytes.Buffer
+ for _, z := range x {
+ runtime.GC()
+ fmt.Fprintf(&buf, "%s %s ", z.x.(string), z.y.(string))
+ }
+
+ if buf.String() != "a b c d e f g h " {
+ println("BUG wrong output\n", buf.String())
+ }
+}
diff --git a/test/fixedbugs/bug484.go b/test/fixedbugs/bug484.go
new file mode 100644
index 000000000..c664b83af
--- /dev/null
+++ b/test/fixedbugs/bug484.go
@@ -0,0 +1,90 @@
+// run
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The liveness code used to say that, in func g, s was live
+// starting at its declaration, because it appears to have its
+// address taken by the closure (different s, but the parser
+// gets slightly confused, a separate bug). The liveness analysis
+// saw s as having its address taken but the register optimizer
+// did not. This mismatch meant that s would be marked live
+// (and therefore initialized) at the call to f, but the register optimizer
+// would optimize away the initialization of s before f, causing the
+// garbage collector to use unused data.
+// The register optimizer has been changed to respect the
+// same "address taken" flag that the liveness analysis uses,
+// even if it cannot see any address being taken in the actual
+// machine code. This is conservative but keeps the two consistent,
+// which is the most important thing.
+
+package main
+
+import "runtime"
+
+var c bool
+
+func f() interface{} {
+ if c { // disable inlining
+ f()
+ }
+ runtime.GC()
+ return nil
+}
+
+func g() {
+ if c { // disable inlining
+ g()
+ }
+ var s interface{}
+ _ = func() {
+ s := f()
+ _ = s
+ }
+ s = f()
+ useiface(s)
+ useiface(s)
+}
+
+func useiface(x interface{}) {
+ if c { // disable inlining
+ useiface(x)
+ }
+}
+
+func h() {
+ if c { // disable inlining
+ h()
+ }
+ var x [16]uintptr
+ for i := range x {
+ x[i] = 1
+ }
+
+ useint(x[0])
+ useint(x[1])
+ useint(x[2])
+ useint(x[3])
+}
+
+func useint(x uintptr) {
+ if c { // disable inlining
+ useint(x)
+ }
+}
+
+func main() {
+ // scribble non-zero values on stack
+ h()
+ // call function that used to let the garbage collector
+ // see uninitialized stack values; it will see the
+ // nonzero values.
+ g()
+}
+
+func big(x int) {
+ if x >= 0 {
+ big(x-1)
+ }
+}
diff --git a/test/fixedbugs/bug485.go b/test/fixedbugs/bug485.go
new file mode 100644
index 000000000..1544753ab
--- /dev/null
+++ b/test/fixedbugs/bug485.go
@@ -0,0 +1,39 @@
+// run
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Gccgo chose the wrong embedded method when the same type appeared
+// at different levels and the correct choice was not the first
+// appearance of the type in a depth-first search.
+
+package main
+
+type embedded string
+
+func (s embedded) val() string {
+ return string(s)
+}
+
+type A struct {
+ embedded
+}
+
+type B struct {
+ A
+ embedded
+}
+
+func main() {
+ b := &B{
+ A: A{
+ embedded: "a",
+ },
+ embedded: "b",
+ }
+ s := b.val()
+ if s != "b" {
+ panic(s)
+ }
+}
diff --git a/test/fixedbugs/issue1304.go b/test/fixedbugs/issue1304.go
new file mode 100644
index 000000000..1206e1840
--- /dev/null
+++ b/test/fixedbugs/issue1304.go
@@ -0,0 +1,23 @@
+// run
+
+// Copyright 2014 The Go 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 a = 1
+
+func main() {
+ defer func() {
+ recover()
+ if a != 2 {
+ println("BUG a =", a)
+ }
+ }()
+ a = 2
+ b := a - a
+ c := 4
+ a = c / b
+ a = 3
+}
diff --git a/test/fixedbugs/issue3705.go b/test/fixedbugs/issue3705.go
index c19bcea1c..64ef38b10 100644
--- a/test/fixedbugs/issue3705.go
+++ b/test/fixedbugs/issue3705.go
@@ -6,4 +6,4 @@
package p
-func init() // ERROR "missing function body"
+func init() // ERROR "missing function body|cannot declare init"
diff --git a/test/fixedbugs/issue4251.go b/test/fixedbugs/issue4251.go
index 4adec2bab..3668d4c89 100644
--- a/test/fixedbugs/issue4251.go
+++ b/test/fixedbugs/issue4251.go
@@ -9,13 +9,13 @@
package p
func F1(s []byte) []byte {
- return s[2:1] // ERROR "invalid slice index"
+ return s[2:1] // ERROR "invalid slice index|inverted slice range"
}
func F2(a [10]byte) []byte {
- return a[2:1] // ERROR "invalid slice index"
+ return a[2:1] // ERROR "invalid slice index|inverted slice range"
}
func F3(s string) string {
- return s[2:1] // ERROR "invalid slice index"
+ return s[2:1] // ERROR "invalid slice index|inverted slice range"
}
diff --git a/test/fixedbugs/issue4388.go b/test/fixedbugs/issue4388.go
new file mode 100644
index 000000000..2e052e138
--- /dev/null
+++ b/test/fixedbugs/issue4388.go
@@ -0,0 +1,56 @@
+// run
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "fmt"
+ "io"
+ "runtime"
+)
+
+type T struct {
+ io.Closer
+}
+
+func f1() {
+ // The 4 here and below depends on the number of internal runtime frames
+ // that sit between a deferred function called during panic and
+ // the original frame. If that changes, this test will start failing and
+ // the number here will need to be updated.
+ defer checkLine(4)
+ var t *T
+ var c io.Closer = t
+ c.Close()
+}
+
+func f2() {
+ defer checkLine(4)
+ var t T
+ var c io.Closer = t
+ c.Close()
+}
+
+func main() {
+ f1()
+ f2()
+}
+
+func checkLine(n int) {
+ if err := recover(); err == nil {
+ panic("did not panic")
+ }
+ var file string
+ var line int
+ for i := 1; i <= n; i++ {
+ _, file, line, _ = runtime.Caller(i)
+ if file != "<autogenerated>" || line != 1 {
+ continue
+ }
+ return
+ }
+ panic(fmt.Sprintf("expected <autogenerated>:1 have %s:%d", file, line))
+}
diff --git a/test/fixedbugs/issue4405.go b/test/fixedbugs/issue4405.go
index c0d808559..b8458d776 100644
--- a/test/fixedbugs/issue4405.go
+++ b/test/fixedbugs/issue4405.go
@@ -8,8 +8,8 @@ package p
const (
_ = iota
- _ // ERROR "illegal character"
- _ // ERROR "illegal character"
- _ // ERROR "illegal character"
- _ // ERROR "illegal character"
+ _ // ERROR "illegal character|invalid character"
+ _ // ERROR "illegal character|invalid character"
+ _ // ERROR "illegal character|invalid character"
+ _ // ERROR "illegal character|invalid character"
)
diff --git a/test/fixedbugs/issue4429.go b/test/fixedbugs/issue4429.go
index 8a93b0204..6822760ef 100644
--- a/test/fixedbugs/issue4429.go
+++ b/test/fixedbugs/issue4429.go
@@ -12,5 +12,5 @@ type a struct {
func main() {
av := a{};
- *a(av); // ERROR "invalid indirect"
+ _ = *a(av); // ERROR "invalid indirect|expected pointer"
}
diff --git a/test/fixedbugs/issue4510.dir/f1.go b/test/fixedbugs/issue4510.dir/f1.go
index 1e642e4ce..7e2cffa5d 100644
--- a/test/fixedbugs/issue4510.dir/f1.go
+++ b/test/fixedbugs/issue4510.dir/f1.go
@@ -4,6 +4,6 @@
package p
-import "fmt" // ERROR "fmt redeclared"
+import "fmt" // ERROR "fmt redeclared|imported"
var _ = fmt.Printf
diff --git a/test/fixedbugs/issue4517d.go b/test/fixedbugs/issue4517d.go
index f601db66f..3d727d433 100644
--- a/test/fixedbugs/issue4517d.go
+++ b/test/fixedbugs/issue4517d.go
@@ -6,4 +6,4 @@
package p
-import init "fmt" // ERROR "cannot import package as init - init must be a func"
+import init "fmt" // ERROR "cannot import package as init"
diff --git a/test/fixedbugs/issue4545.go b/test/fixedbugs/issue4545.go
index 501caadb0..c37ccef7c 100644
--- a/test/fixedbugs/issue4545.go
+++ b/test/fixedbugs/issue4545.go
@@ -13,7 +13,7 @@ import "fmt"
func main() {
var s uint
- fmt.Println(1.0 + 1<<s) // ERROR "invalid operation|non-integer type"
+ fmt.Println(1.0 + 1<<s) // ERROR "invalid operation|non-integer type|incompatible type"
x := 1.0 + 1<<s // ERROR "invalid operation|non-integer type"
_ = x
}
diff --git a/test/fixedbugs/issue4610.go b/test/fixedbugs/issue4610.go
index bc6bfe790..d56c6d3e8 100644
--- a/test/fixedbugs/issue4610.go
+++ b/test/fixedbugs/issue4610.go
@@ -12,6 +12,6 @@ type bar struct {
func main() {
var foo bar
- _ = &foo{} // ERROR "is not a type"
-}
+ _ = &foo{} // ERROR "is not a type|expected .;."
+} // GCCGO_ERROR "expected declaration"
diff --git a/test/fixedbugs/issue4618.go b/test/fixedbugs/issue4618.go
index 335feaadb..fe875b350 100644
--- a/test/fixedbugs/issue4618.go
+++ b/test/fixedbugs/issue4618.go
@@ -9,6 +9,7 @@ package main
import (
"fmt"
"os"
+ "runtime"
"testing"
)
@@ -29,11 +30,11 @@ func G() {
func main() {
nf := testing.AllocsPerRun(100, F)
ng := testing.AllocsPerRun(100, G)
- if int(nf) != 1 {
+ if int(nf) > 1 {
fmt.Printf("AllocsPerRun(100, F) = %v, want 1\n", nf)
os.Exit(1)
}
- if int(ng) != 0 {
+ if int(ng) != 0 && (runtime.Compiler != "gccgo" || int(ng) != 1) {
fmt.Printf("AllocsPerRun(100, G) = %v, want 0\n", ng)
os.Exit(1)
}
diff --git a/test/fixedbugs/issue4654.go b/test/fixedbugs/issue4654.go
index 170594e4b..d3f582b20 100644
--- a/test/fixedbugs/issue4654.go
+++ b/test/fixedbugs/issue4654.go
@@ -12,32 +12,32 @@ package p
import "unsafe"
func f() {
- defer int(0) // ERROR "defer requires function call, not conversion"
- go string([]byte("abc")) // ERROR "go requires function call, not conversion"
+ defer int(0) // ERROR "defer requires function call, not conversion|is not used"
+ go string([]byte("abc")) // ERROR "go requires function call, not conversion|is not used"
var c complex128
var f float64
var t struct {X int}
var x []int
- defer append(x, 1) // ERROR "defer discards result of append"
- defer cap(x) // ERROR "defer discards result of cap"
- defer complex(1, 2) // ERROR "defer discards result of complex"
- defer complex(f, 1) // ERROR "defer discards result of complex"
- defer imag(1i) // ERROR "defer discards result of imag"
- defer imag(c) // ERROR "defer discards result of imag"
- defer len(x) // ERROR "defer discards result of len"
- defer make([]int, 1) // ERROR "defer discards result of make"
- defer make(chan bool) // ERROR "defer discards result of make"
- defer make(map[string]int) // ERROR "defer discards result of make"
- defer new(int) // ERROR "defer discards result of new"
- defer real(1i) // ERROR "defer discards result of real"
- defer real(c) // ERROR "defer discards result of real"
- defer append(x, 1) // ERROR "defer discards result of append"
- defer append(x, 1) // ERROR "defer discards result of append"
- defer unsafe.Alignof(t.X) // ERROR "defer discards result of unsafe.Alignof"
- defer unsafe.Offsetof(t.X) // ERROR "defer discards result of unsafe.Offsetof"
- defer unsafe.Sizeof(t) // ERROR "defer discards result of unsafe.Sizeof"
+ defer append(x, 1) // ERROR "defer discards result of append|is not used"
+ defer cap(x) // ERROR "defer discards result of cap|is not used"
+ defer complex(1, 2) // ERROR "defer discards result of complex|is not used"
+ defer complex(f, 1) // ERROR "defer discards result of complex|is not used"
+ defer imag(1i) // ERROR "defer discards result of imag|is not used"
+ defer imag(c) // ERROR "defer discards result of imag|is not used"
+ defer len(x) // ERROR "defer discards result of len|is not used"
+ defer make([]int, 1) // ERROR "defer discards result of make|is not used"
+ defer make(chan bool) // ERROR "defer discards result of make|is not used"
+ defer make(map[string]int) // ERROR "defer discards result of make|is not used"
+ defer new(int) // ERROR "defer discards result of new|is not used"
+ defer real(1i) // ERROR "defer discards result of real|is not used"
+ defer real(c) // ERROR "defer discards result of real|is not used"
+ defer append(x, 1) // ERROR "defer discards result of append|is not used"
+ defer append(x, 1) // ERROR "defer discards result of append|is not used"
+ defer unsafe.Alignof(t.X) // ERROR "defer discards result of unsafe.Alignof|is not used"
+ defer unsafe.Offsetof(t.X) // ERROR "defer discards result of unsafe.Offsetof|is not used"
+ defer unsafe.Sizeof(t) // ERROR "defer discards result of unsafe.Sizeof|is not used"
defer copy(x, x) // ok
m := make(map[int]int)
@@ -47,8 +47,8 @@ func f() {
defer println(1) // ok
defer recover() // ok
- int(0) // ERROR "int\(0\) evaluated but not used"
- string([]byte("abc")) // ERROR "string\(.*\) evaluated but not used"
+ int(0) // ERROR "int\(0\) evaluated but not used|is not used"
+ string([]byte("abc")) // ERROR "string\(.*\) evaluated but not used|is not used"
append(x, 1) // ERROR "not used"
cap(x) // ERROR "not used"
diff --git a/test/fixedbugs/issue4667.go b/test/fixedbugs/issue4667.go
index 3a00a3195..18d773c2c 100644
--- a/test/fixedbugs/issue4667.go
+++ b/test/fixedbugs/issue4667.go
@@ -26,11 +26,11 @@ func F() {
func main() {
nf := testing.AllocsPerRun(100, F)
ng := testing.AllocsPerRun(100, G)
- if int(nf) != 1 {
+ if int(nf) > 1 {
fmt.Printf("AllocsPerRun(100, F) = %v, want 1\n", nf)
os.Exit(1)
}
- if int(ng) != 1 {
+ if int(ng) > 1 {
fmt.Printf("AllocsPerRun(100, G) = %v, want 1\n", ng)
os.Exit(1)
}
diff --git a/test/fixedbugs/issue4776.go b/test/fixedbugs/issue4776.go
index c38dc09b1..13781af1f 100644
--- a/test/fixedbugs/issue4776.go
+++ b/test/fixedbugs/issue4776.go
@@ -6,5 +6,5 @@
// Issue 4776: missing package declaration error should be fatal.
-type MyInt int32 // ERROR "package statement must be first"
+type MyInt int32 // ERROR "package statement must be first|package clause"
diff --git a/test/fixedbugs/issue4813.go b/test/fixedbugs/issue4813.go
index 20dc58795..f560b2fac 100644
--- a/test/fixedbugs/issue4813.go
+++ b/test/fixedbugs/issue4813.go
@@ -28,25 +28,25 @@ var (
var (
a1 = A[i]
a2 = A[f]
- a3 = A[f2] // ERROR "truncated"
+ a3 = A[f2] // ERROR "truncated|must be integer"
a4 = A[c]
- a5 = A[c2] // ERROR "truncated"
+ a5 = A[c2] // ERROR "truncated|must be integer"
a6 = A[vf] // ERROR "non-integer|must be integer"
a7 = A[vc] // ERROR "non-integer|must be integer"
s1 = S[i]
s2 = S[f]
- s3 = S[f2] // ERROR "truncated"
+ s3 = S[f2] // ERROR "truncated|must be integer"
s4 = S[c]
- s5 = S[c2] // ERROR "truncated"
+ s5 = S[c2] // ERROR "truncated|must be integer"
s6 = S[vf] // ERROR "non-integer|must be integer"
s7 = S[vc] // ERROR "non-integer|must be integer"
t1 = T[i]
t2 = T[f]
- t3 = T[f2] // ERROR "truncated"
+ t3 = T[f2] // ERROR "truncated|must be integer"
t4 = T[c]
- t5 = T[c2] // ERROR "truncated"
+ t5 = T[c2] // ERROR "truncated|must be integer"
t6 = T[vf] // ERROR "non-integer|must be integer"
t7 = T[vc] // ERROR "non-integer|must be integer"
)
diff --git a/test/fixedbugs/issue4847.go b/test/fixedbugs/issue4847.go
index a99e80129..91a6568f2 100644
--- a/test/fixedbugs/issue4847.go
+++ b/test/fixedbugs/issue4847.go
@@ -19,6 +19,6 @@ func matchList(s *S) E { return matcher(matchAnyFn)(s) }
var foo = matcher(matchList)
-var matchAny = matcher(matchList) // ERROR "initialization loop"
+var matchAny = matcher(matchList) // ERROR "initialization loop|depends upon itself"
func matchAnyFn(s *S) (err E) { return matchAny(s) }
diff --git a/test/fixedbugs/issue5089.go b/test/fixedbugs/issue5089.go
index 14d6bde98..81b9f0521 100644
--- a/test/fixedbugs/issue5089.go
+++ b/test/fixedbugs/issue5089.go
@@ -8,8 +8,8 @@
package p
-import "bufio"
+import "bufio" // GCCGO_ERROR "previous"
-func (b *bufio.Reader) Buffered() int { // ERROR "non-local"
+func (b *bufio.Reader) Buffered() int { // ERROR "non-local|redefinition"
return -1
}
diff --git a/test/fixedbugs/issue5172.go b/test/fixedbugs/issue5172.go
index 2dd542a5d..a6acbd3db 100644
--- a/test/fixedbugs/issue5172.go
+++ b/test/fixedbugs/issue5172.go
@@ -14,6 +14,6 @@ type foo struct {
func main() {
var f foo
- go f.bar()
- defer f.bar()
+ go f.bar() // GCCGO_ERROR "undefined"
+ defer f.bar() // GCCGO_ERROR "undefined"
}
diff --git a/test/fixedbugs/issue5358.go b/test/fixedbugs/issue5358.go
index 75aa9533d..c2b1da9e0 100644
--- a/test/fixedbugs/issue5358.go
+++ b/test/fixedbugs/issue5358.go
@@ -13,5 +13,5 @@ func f(x int, y ...int) {}
func g() (int, []int)
func main() {
- f(g()) // ERROR "as type int in"
+ f(g()) // ERROR "as type int in|incompatible type"
}
diff --git a/test/fixedbugs/issue5493.go b/test/fixedbugs/issue5493.go
index affc07b58..2ee0398af 100644
--- a/test/fixedbugs/issue5493.go
+++ b/test/fixedbugs/issue5493.go
@@ -31,9 +31,10 @@ func run() error {
}
func main() {
- // Does not work on 32-bits due to partially conservative GC.
+ // Does not work on 32-bits, or with gccgo, due to partially
+ // conservative GC.
// Try to enable when we have fully precise GC.
- if runtime.GOARCH != "amd64" {
+ if runtime.GOARCH != "amd64" || runtime.Compiler == "gccgo" {
return
}
count = N
diff --git a/test/fixedbugs/issue5581.go b/test/fixedbugs/issue5581.go
index 8c2d59729..36a4ad671 100644
--- a/test/fixedbugs/issue5581.go
+++ b/test/fixedbugs/issue5581.go
@@ -26,7 +26,7 @@ type Foo struct {
type Bar struct {
A *Foo
- B chan Blah // ERROR "undefined: Blah"
+ B chan Blah // ERROR "undefined.*Blah"
}
func main() {
diff --git a/test/fixedbugs/issue5793.go b/test/fixedbugs/issue5793.go
new file mode 100644
index 000000000..f5a9965f2
--- /dev/null
+++ b/test/fixedbugs/issue5793.go
@@ -0,0 +1,36 @@
+// run
+
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 5793: calling 2-arg builtin with multiple-result f() call expression gives
+// spurious error.
+
+package main
+
+func complexArgs() (float64, float64) {
+ return 5, 7
+}
+
+func appendArgs() ([]string, string) {
+ return []string{"foo"}, "bar"
+}
+
+func appendMultiArgs() ([]byte, byte, byte) {
+ return []byte{'a', 'b'}, '1', '2'
+}
+
+func main() {
+ if c := complex(complexArgs()); c != 5+7i {
+ panic(c)
+ }
+
+ if s := append(appendArgs()); len(s) != 2 || s[0] != "foo" || s[1] != "bar" {
+ panic(s)
+ }
+
+ if b := append(appendMultiArgs()); len(b) != 4 || b[0] != 'a' || b[1] != 'b' || b[2] != '1' || b[3] != '2' {
+ panic(b)
+ }
+}
diff --git a/test/fixedbugs/issue5957.dir/c.go b/test/fixedbugs/issue5957.dir/c.go
index 42c88177b..a1781d4d4 100644
--- a/test/fixedbugs/issue5957.dir/c.go
+++ b/test/fixedbugs/issue5957.dir/c.go
@@ -1,12 +1,12 @@
package p
import (
- "./a" // ERROR "imported and not used: \x22a\x22 as surprise"
- "./b" // ERROR "imported and not used: \x22b\x22 as surprise2"
- b "./b" // ERROR "imported and not used: \x22b\x22$"
- foo "math" // ERROR "imported and not used: \x22math\x22 as foo"
+ "./a" // ERROR "imported and not used: \x22a\x22 as surprise|imported and not used: surprise"
+ "./b" // GC_ERROR "imported and not used: \x22b\x22 as surprise2|imported and not used: surprise2"
+ b "./b" // ERROR "imported and not used: \x22b\x22$|imported and not used: surprise2"
+ foo "math" // ERROR "imported and not used: \x22math\x22 as foo|imported and not used: math"
"fmt" // actually used
- "strings" // ERROR "imported and not used: \x22strings\x22"
+ "strings" // ERROR "imported and not used: \x22strings\x22|imported and not used: strings"
)
var _ = fmt.Printf
diff --git a/test/fixedbugs/issue6295.dir/p0.go b/test/fixedbugs/issue6295.dir/p0.go
new file mode 100644
index 000000000..cf86fbcb5
--- /dev/null
+++ b/test/fixedbugs/issue6295.dir/p0.go
@@ -0,0 +1,13 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p0
+
+type T0 interface {
+ m0()
+}
+
+type S0 struct{}
+
+func (S0) m0() {}
diff --git a/test/fixedbugs/issue6295.dir/p1.go b/test/fixedbugs/issue6295.dir/p1.go
new file mode 100644
index 000000000..974d02fb0
--- /dev/null
+++ b/test/fixedbugs/issue6295.dir/p1.go
@@ -0,0 +1,26 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p1
+
+import "./p0"
+
+type T1 interface {
+ p0.T0
+ m1()
+}
+
+type S1 struct {
+ p0.S0
+}
+
+func (S1) m1() {}
+
+func NewT0() p0.T0 {
+ return S1{}
+}
+
+func NewT1() T1 {
+ return S1{}
+}
diff --git a/test/fixedbugs/issue6295.dir/p2.go b/test/fixedbugs/issue6295.dir/p2.go
new file mode 100644
index 000000000..4703ec035
--- /dev/null
+++ b/test/fixedbugs/issue6295.dir/p2.go
@@ -0,0 +1,19 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "./p0"
+ "./p1"
+)
+
+var (
+ _ p0.T0 = p0.S0{}
+ _ p0.T0 = p1.S1{}
+ _ p0.T0 = p1.NewT0()
+ _ p0.T0 = p1.NewT1() // same as p1.S1{}
+)
+
+func main() {}
diff --git a/test/fixedbugs/issue6295.go b/test/fixedbugs/issue6295.go
new file mode 100644
index 000000000..b8da21272
--- /dev/null
+++ b/test/fixedbugs/issue6295.go
@@ -0,0 +1,10 @@
+// compiledir
+
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 6295: qualified name of unexported methods
+// is corrupted during import.
+
+package ignored
diff --git a/test/fixedbugs/issue6402.go b/test/fixedbugs/issue6402.go
new file mode 100644
index 000000000..da5980c9a
--- /dev/null
+++ b/test/fixedbugs/issue6402.go
@@ -0,0 +1,13 @@
+// errorcheck
+
+// Copyright 2014 The Go 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 6402: spurious 'use of untyped nil' error
+
+package p
+
+func f() uintptr {
+ return nil // ERROR "cannot use nil as type uintptr in return argument"
+}
diff --git a/test/fixedbugs/issue6403.go b/test/fixedbugs/issue6403.go
new file mode 100644
index 000000000..b61e2e225
--- /dev/null
+++ b/test/fixedbugs/issue6403.go
@@ -0,0 +1,14 @@
+// errorcheck
+
+// Copyright 2014 The Go 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 6403: fix spurious 'const initializer is not a constant' error
+
+package p
+
+import "syscall"
+
+const A int = syscall.X // ERROR "undefined: syscall.X"
+const B int = voidpkg.X // ERROR "undefined: voidpkg"
diff --git a/test/fixedbugs/issue6405.go b/test/fixedbugs/issue6405.go
new file mode 100644
index 000000000..b4551cc25
--- /dev/null
+++ b/test/fixedbugs/issue6405.go
@@ -0,0 +1,13 @@
+// errorcheck
+
+// Copyright 2014 The Go 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 6405: spurious 'not enough arguments to return' error
+
+package p
+
+func Open() (int, error) {
+ return OpenFile() // ERROR "undefined: OpenFile"
+}
diff --git a/test/fixedbugs/issue6406.go b/test/fixedbugs/issue6406.go
new file mode 100644
index 000000000..5491193ef
--- /dev/null
+++ b/test/fixedbugs/issue6406.go
@@ -0,0 +1,12 @@
+// errorcheck
+
+// Copyright 2014 The Go 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() {
+ s = "bob" // ERROR "undefined.*s"
+ _ = s // ERROR "undefined.*s"
+}
diff --git a/test/fixedbugs/issue6500.go b/test/fixedbugs/issue6500.go
new file mode 100644
index 000000000..b265f9ae3
--- /dev/null
+++ b/test/fixedbugs/issue6500.go
@@ -0,0 +1,29 @@
+// errorcheck
+
+// Copyright 2014 The Go 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 6500: missing error when fallthrough appears in a block.
+
+package main
+
+func main() {
+ var x int
+ switch x {
+ case 0:
+ {
+ fallthrough // ERROR "fallthrough"
+ }
+ case 1:
+ {
+ switch x {
+ case 2:
+ fallthrough
+ case 3:
+ }
+ }
+ fallthrough
+ default:
+ }
+}
diff --git a/test/fixedbugs/issue6572.go b/test/fixedbugs/issue6572.go
new file mode 100644
index 000000000..e75da54c9
--- /dev/null
+++ b/test/fixedbugs/issue6572.go
@@ -0,0 +1,21 @@
+// errorcheck
+
+// Copyright 2014 The Go 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 foo() (T, T) { // ERROR "undefined"
+ return 0, 0
+}
+
+func bar() (T, string, T) { // ERROR "undefined"
+ return 0, "", 0
+}
+
+func main() {
+ var x, y, z int
+ x, y = foo()
+ x, y, z = bar() // ERROR "cannot (use type|assign) string"
+}
diff --git a/test/fixedbugs/issue6789.dir/a.go b/test/fixedbugs/issue6789.dir/a.go
new file mode 100644
index 000000000..9c90e0740
--- /dev/null
+++ b/test/fixedbugs/issue6789.dir/a.go
@@ -0,0 +1,14 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+type unexported struct {
+ a int
+ b bool
+}
+
+type Struct struct {
+ unexported
+}
diff --git a/test/fixedbugs/issue6789.dir/b.go b/test/fixedbugs/issue6789.dir/b.go
new file mode 100644
index 000000000..b6a6fc317
--- /dev/null
+++ b/test/fixedbugs/issue6789.dir/b.go
@@ -0,0 +1,12 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "./a"
+
+type s a.Struct
+
+func main() {
+}
diff --git a/test/fixedbugs/issue6789.go b/test/fixedbugs/issue6789.go
new file mode 100644
index 000000000..e3a2c3320
--- /dev/null
+++ b/test/fixedbugs/issue6789.go
@@ -0,0 +1,10 @@
+// rundir
+
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 6789: gccgo failed to find the hash function for an
+// unexported struct embedded in an exported struct.
+
+package ignored
diff --git a/test/fixedbugs/issue6847.go b/test/fixedbugs/issue6847.go
new file mode 100644
index 000000000..e6427e19a
--- /dev/null
+++ b/test/fixedbugs/issue6847.go
@@ -0,0 +1,85 @@
+// compile
+
+// Copyright 2014 The Go 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 6847: select clauses involving implicit conversion
+// of channels trigger a spurious typechecking error during walk.
+
+package p
+
+type I1 interface {
+ String()
+}
+type I2 interface {
+ String()
+}
+
+func F() {
+ var (
+ cr <-chan int
+ cs chan<- int
+ c chan int
+
+ ccr chan (<-chan int)
+ ccs chan chan<- int
+ cc chan chan int
+
+ ok bool
+ )
+ // Send cases.
+ select {
+ case ccr <- cr:
+ case ccr <- c:
+ }
+ select {
+ case ccs <- cs:
+ case ccs <- c:
+ }
+ select {
+ case ccr <- c:
+ default:
+ }
+ // Receive cases.
+ select {
+ case cr = <-cc:
+ case cs = <-cc:
+ case c = <-cc:
+ }
+ select {
+ case cr = <-cc:
+ default:
+ }
+ select {
+ case cr, ok = <-cc:
+ case cs, ok = <-cc:
+ case c = <-cc:
+ }
+ // Interfaces.
+ var (
+ c1 chan I1
+ c2 chan I2
+ x1 I1
+ x2 I2
+ )
+ select {
+ case c1 <- x1:
+ case c1 <- x2:
+ case c2 <- x1:
+ case c2 <- x2:
+ }
+ select {
+ case x1 = <-c1:
+ case x1 = <-c2:
+ case x2 = <-c1:
+ case x2 = <-c2:
+ }
+ select {
+ case x1, ok = <-c1:
+ case x1, ok = <-c2:
+ case x2, ok = <-c1:
+ case x2, ok = <-c2:
+ }
+ _ = ok
+}
diff --git a/test/fixedbugs/issue6889.go b/test/fixedbugs/issue6889.go
new file mode 100644
index 000000000..46bb5dacf
--- /dev/null
+++ b/test/fixedbugs/issue6889.go
@@ -0,0 +1,103 @@
+// errorcheck
+
+// Copyright 2014 The Go 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 6889: confusing error message: ovf in mpaddxx
+
+package main
+
+const (
+ f1 = 1
+ f2 = f1 * 2
+ f3 = f2 * 3
+ f4 = f3 * 4
+ f5 = f4 * 5
+ f6 = f5 * 6
+ f7 = f6 * 7
+ f8 = f7 * 8
+ f9 = f8 * 9
+ f10 = f9 * 10
+ f11 = f10 * 11
+ f12 = f11 * 12
+ f13 = f12 * 13
+ f14 = f13 * 14
+ f15 = f14 * 15
+ f16 = f15 * 16
+ f17 = f16 * 17
+ f18 = f17 * 18
+ f19 = f18 * 19
+ f20 = f19 * 20
+ f21 = f20 * 21
+ f22 = f21 * 22
+ f23 = f22 * 23
+ f24 = f23 * 24
+ f25 = f24 * 25
+ f26 = f25 * 26
+ f27 = f26 * 27
+ f28 = f27 * 28
+ f29 = f28 * 29
+ f30 = f29 * 30
+ f31 = f30 * 31
+ f32 = f31 * 32
+ f33 = f32 * 33
+ f34 = f33 * 34
+ f35 = f34 * 35
+ f36 = f35 * 36
+ f37 = f36 * 37
+ f38 = f37 * 38
+ f39 = f38 * 39
+ f40 = f39 * 40
+ f41 = f40 * 41
+ f42 = f41 * 42
+ f43 = f42 * 43
+ f44 = f43 * 44
+ f45 = f44 * 45
+ f46 = f45 * 46
+ f47 = f46 * 47
+ f48 = f47 * 48
+ f49 = f48 * 49
+ f50 = f49 * 50
+ f51 = f50 * 51
+ f52 = f51 * 52
+ f53 = f52 * 53
+ f54 = f53 * 54
+ f55 = f54 * 55
+ f56 = f55 * 56
+ f57 = f56 * 57
+ f58 = f57 * 58
+ f59 = f58 * 59
+ f60 = f59 * 60
+ f61 = f60 * 61
+ f62 = f61 * 62
+ f63 = f62 * 63
+ f64 = f63 * 64
+ f65 = f64 * 65
+ f66 = f65 * 66
+ f67 = f66 * 67
+ f68 = f67 * 68
+ f69 = f68 * 69
+ f70 = f69 * 70
+ f71 = f70 * 71
+ f72 = f71 * 72
+ f73 = f72 * 73
+ f74 = f73 * 74
+ f75 = f74 * 75
+ f76 = f75 * 76
+ f77 = f76 * 77
+ f78 = f77 * 78
+ f79 = f78 * 79
+ f80 = f79 * 80
+ f81 = f80 * 81
+ f82 = f81 * 82
+ f83 = f82 * 83
+ f84 = f83 * 84
+ f85 = f84 * 85
+ f86 = f85 * 86
+ f87 = f86 * 87
+ f88 = f87 * 88
+ f89 = f88 * 89
+ f90 = f89 * 90
+ f91 = f90 * 91 // ERROR "overflow"
+)
diff --git a/test/fixedbugs/issue6899.go b/test/fixedbugs/issue6899.go
new file mode 100644
index 000000000..a693bf285
--- /dev/null
+++ b/test/fixedbugs/issue6899.go
@@ -0,0 +1,13 @@
+// cmpout
+
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "math"
+
+func main() {
+ println(math.Copysign(0, -1))
+}
diff --git a/test/fixedbugs/issue6899.out b/test/fixedbugs/issue6899.out
new file mode 100644
index 000000000..e2375f077
--- /dev/null
+++ b/test/fixedbugs/issue6899.out
@@ -0,0 +1 @@
+-0.000000e+000
diff --git a/test/fixedbugs/issue6902.go b/test/fixedbugs/issue6902.go
new file mode 100644
index 000000000..5c2c545d2
--- /dev/null
+++ b/test/fixedbugs/issue6902.go
@@ -0,0 +1,21 @@
+// run
+
+// Copyright 2014 The Go 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 6902: confusing printing of large floating point constants
+
+package main
+
+import (
+ "os"
+)
+
+var x = -1e-10000
+
+func main() {
+ if x != 0 {
+ os.Exit(1)
+ }
+}
diff --git a/test/fixedbugs/issue6964.go b/test/fixedbugs/issue6964.go
new file mode 100644
index 000000000..821735c08
--- /dev/null
+++ b/test/fixedbugs/issue6964.go
@@ -0,0 +1,11 @@
+// errorcheck
+
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func main() {
+ _ = string(-4 + 2i + 2) // ERROR "-4\+2i"
+}
diff --git a/test/fixedbugs/issue7023.dir/a.go b/test/fixedbugs/issue7023.dir/a.go
new file mode 100644
index 000000000..cdb543209
--- /dev/null
+++ b/test/fixedbugs/issue7023.dir/a.go
@@ -0,0 +1,10 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+func Foo() {
+ goto bar
+bar:
+}
diff --git a/test/fixedbugs/issue7023.dir/b.go b/test/fixedbugs/issue7023.dir/b.go
new file mode 100644
index 000000000..c6fe40dfa
--- /dev/null
+++ b/test/fixedbugs/issue7023.dir/b.go
@@ -0,0 +1,11 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package b
+
+import (
+ "./a"
+)
+
+var f = a.Foo
diff --git a/test/fixedbugs/issue7023.go b/test/fixedbugs/issue7023.go
new file mode 100644
index 000000000..f18c6113e
--- /dev/null
+++ b/test/fixedbugs/issue7023.go
@@ -0,0 +1,10 @@
+// compiledir
+
+// Copyright 2014 The Go 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 7023: corrupted export data when an inlined function
+// contains a goto.
+
+package ignored
diff --git a/test/fixedbugs/issue7044.go b/test/fixedbugs/issue7044.go
new file mode 100644
index 000000000..cac6a7683
--- /dev/null
+++ b/test/fixedbugs/issue7044.go
@@ -0,0 +1,43 @@
+// run
+
+// Copyright 2014 The Go 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 7044: bad AMOVFD and AMOVDF assembly generation on
+// arm for registers above 7.
+
+package main
+
+import (
+ "fmt"
+ "reflect"
+)
+
+func f() [16]float32 {
+ f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15 :=
+ float32(1), float32(1), float32(1), float32(1), float32(1), float32(1), float32(1), float32(1), float32(1), float32(1), float32(1), float32(1), float32(1), float32(1), float32(1), float32(1)
+ // Use all 16 registers to do float32 --> float64 conversion.
+ d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15 :=
+ float64(f0), float64(f1), float64(f2), float64(f3), float64(f4), float64(f5), float64(f6), float64(f7), float64(f8), float64(f9), float64(f10), float64(f11), float64(f12), float64(f13), float64(f14), float64(f15)
+ // Use all 16 registers to do float64 --> float32 conversion.
+ g0, g1, g2, g3, g4, g5, g6, g7, g8, g9, g10, g11, g12, g13, g14, g15 :=
+ float32(d0), float32(d1), float32(d2), float32(d3), float32(d4), float32(d5), float32(d6), float32(d7), float32(d8), float32(d9), float32(d10), float32(d11), float32(d12), float32(d13), float32(d14), float32(d15)
+ // Force another conversion, so that the previous conversion doesn't
+ // get optimized away into constructing the returned array. With current
+ // optimizations, constructing the returned array uses only
+ // a single register.
+ e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15 :=
+ float64(g0), float64(g1), float64(g2), float64(g3), float64(g4), float64(g5), float64(g6), float64(g7), float64(g8), float64(g9), float64(g10), float64(g11), float64(g12), float64(g13), float64(g14), float64(g15)
+ return [16]float32{
+ float32(e0), float32(e1), float32(e2), float32(e3), float32(e4), float32(e5), float32(e6), float32(e7), float32(e8), float32(e9), float32(e10), float32(e11), float32(e12), float32(e13), float32(e14), float32(e15),
+ }
+}
+
+func main() {
+ want := [16]float32{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
+ got := f()
+ if !reflect.DeepEqual(got, want) {
+ fmt.Printf("f() = %#v; want %#v\n", got, want)
+ }
+}
diff --git a/test/fixedbugs/issue7050.go b/test/fixedbugs/issue7050.go
new file mode 100644
index 000000000..e58b68404
--- /dev/null
+++ b/test/fixedbugs/issue7050.go
@@ -0,0 +1,19 @@
+// run
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "fmt"
+ "os"
+)
+
+func main() {
+ _, err := os.Stdout.Write(nil)
+ if err != nil {
+ fmt.Printf("BUG: os.Stdout.Write(nil) = %v\n", err)
+ }
+}
diff --git a/test/fixedbugs/issue7083.go b/test/fixedbugs/issue7083.go
new file mode 100644
index 000000000..79bfd3b5e
--- /dev/null
+++ b/test/fixedbugs/issue7083.go
@@ -0,0 +1,22 @@
+// run
+
+package main
+
+import "runtime/debug"
+
+func f(m map[int]*string, i int) {
+ s := ""
+ m[i] = &s
+}
+
+func main() {
+ debug.SetGCPercent(0)
+ m := map[int]*string{}
+ for i := 0; i < 40; i++ {
+ f(m, i)
+ if len(*m[i]) != 0 {
+ println("bad length", i, m[i], len(*m[i]))
+ panic("bad length")
+ }
+ }
+}
diff --git a/test/fixedbugs/issue7129.go b/test/fixedbugs/issue7129.go
new file mode 100644
index 000000000..2425cbd34
--- /dev/null
+++ b/test/fixedbugs/issue7129.go
@@ -0,0 +1,21 @@
+// errorcheck
+
+// Copyright 2014 The Go 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 7129: inconsistent "wrong arg type" error for multivalued g in f(g())
+
+package main
+
+func f(int) {}
+
+func g() bool { return true }
+
+func h(int, int) {}
+
+func main() {
+ f(g()) // ERROR "in argument to f"
+ f(true) // ERROR "in argument to f"
+ h(true, true) // ERROR "in argument to h"
+}
diff --git a/test/fixedbugs/issue7150.go b/test/fixedbugs/issue7150.go
new file mode 100644
index 000000000..264958a08
--- /dev/null
+++ b/test/fixedbugs/issue7150.go
@@ -0,0 +1,17 @@
+// errorcheck
+
+// Copyright 2014 The Go 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 7150: array index out of bounds error off by one
+
+package main
+
+func main() {
+ _ = [0]int{-1: 50} // ERROR "array index must be non-negative integer constant"
+ _ = [0]int{0: 0} // ERROR "array index 0 out of bounds \[0:0\]"
+ _ = [0]int{5: 25} // ERROR "array index 5 out of bounds \[0:0\]"
+ _ = [10]int{2: 10, 15: 30} // ERROR "array index 15 out of bounds \[0:10\]"
+ _ = [10]int{5: 5, 1: 1, 12: 12} // ERROR "array index 12 out of bounds \[0:10\]"
+}
diff --git a/test/fixedbugs/issue7153.go b/test/fixedbugs/issue7153.go
new file mode 100644
index 000000000..d70d8582a
--- /dev/null
+++ b/test/fixedbugs/issue7153.go
@@ -0,0 +1,11 @@
+// errorcheck
+
+// Copyright 2014 The Go 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 7153: array invalid index error duplicated on successive bad values
+
+package p
+
+var _ = []int{a: true, true} // ERROR "undefined: a" "cannot use true \(type bool\) as type int in array element"
diff --git a/test/fixedbugs/issue7214.go b/test/fixedbugs/issue7214.go
new file mode 100644
index 000000000..82ddf74c3
--- /dev/null
+++ b/test/fixedbugs/issue7214.go
@@ -0,0 +1,30 @@
+// errorcheck
+
+// Copyright 2014 The Go 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 7214: No duplicate key error for maps with interface{} key type
+
+package p
+
+var _ = map[interface{}]int{2: 1, 2: 1} // ERROR "duplicate key"
+var _ = map[interface{}]int{int(2): 1, int16(2): 1}
+var _ = map[interface{}]int{int16(2): 1, int16(2): 1} // ERROR "duplicate key"
+
+type S string
+
+var _ = map[interface{}]int{"a": 1, "a": 1} // ERROR "duplicate key"
+var _ = map[interface{}]int{"a": 1, S("a"): 1}
+var _ = map[interface{}]int{S("a"): 1, S("a"): 1} // ERROR "duplicate key"
+
+type I interface {
+ f()
+}
+
+type N int
+
+func (N) f() {}
+
+var _ = map[I]int{N(0): 1, N(2): 1}
+var _ = map[I]int{N(2): 1, N(2): 1} // ERROR "duplicate key"
diff --git a/test/fixedbugs/issue7223.go b/test/fixedbugs/issue7223.go
new file mode 100644
index 000000000..c5955d599
--- /dev/null
+++ b/test/fixedbugs/issue7223.go
@@ -0,0 +1,20 @@
+// errorcheck
+
+// Copyright 2014 The Go 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 bits1 uint = 10
+const bits2 uint = 10
+
+func main() {
+ _ = make([]byte, 1<<bits1)
+ _ = make([]byte, 1<<bits2)
+ _ = make([]byte, nil) // ERROR "non-integer.*len"
+ _ = make([]byte, nil, 2) // ERROR "non-integer.*len"
+ _ = make([]byte, 1, nil) // ERROR "non-integer.*cap"
+ _ = make([]byte, true) // ERROR "non-integer.*len"
+ _ = make([]byte, "abc") // ERROR "non-integer.*len"
+}
diff --git a/test/fixedbugs/issue7272.go b/test/fixedbugs/issue7272.go
new file mode 100644
index 000000000..97a08da09
--- /dev/null
+++ b/test/fixedbugs/issue7272.go
@@ -0,0 +1,48 @@
+// compile
+
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 7272: test builtin functions in statement context and in
+// go/defer functions.
+
+package p
+
+func F() {
+ var a []int
+ var c chan int
+ var m map[int]int
+
+ close(c)
+ copy(a, a)
+ delete(m, 0)
+ panic(0)
+ print("foo")
+ println("bar")
+ recover()
+
+ (close(c))
+ (copy(a, a))
+ (delete(m, 0))
+ (panic(0))
+ (print("foo"))
+ (println("bar"))
+ (recover())
+
+ go close(c)
+ go copy(a, a)
+ go delete(m, 0)
+ go panic(0)
+ go print("foo")
+ go println("bar")
+ go recover()
+
+ defer close(c)
+ defer copy(a, a)
+ defer delete(m, 0)
+ defer panic(0)
+ defer print("foo")
+ defer println("bar")
+ defer recover()
+}
diff --git a/test/fixedbugs/issue7310.go b/test/fixedbugs/issue7310.go
new file mode 100644
index 000000000..4a535a1fc
--- /dev/null
+++ b/test/fixedbugs/issue7310.go
@@ -0,0 +1,15 @@
+// errorcheck
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Internal compiler crash used to stop errors during second copy.
+
+package main
+
+func main() {
+ _ = copy(nil, []int{}) // ERROR "use of untyped nil"
+ _ = copy([]int{}, nil) // ERROR "use of untyped nil"
+ _ = 1+true // ERROR "cannot convert true" "mismatched types int and bool"
+}
diff --git a/test/fixedbugs/issue7316.go b/test/fixedbugs/issue7316.go
new file mode 100644
index 000000000..4b32261d4
--- /dev/null
+++ b/test/fixedbugs/issue7316.go
@@ -0,0 +1,37 @@
+// runoutput
+
+// Copyright 2014 The Go 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 7316
+// This test exercises all types of numeric conversions, which was one
+// of the sources of etype mismatch during register allocation in 8g.
+
+package main
+
+import "fmt"
+
+const tpl = `
+func init() {
+ var i %s
+ j := %s(i)
+ _ = %s(j)
+}
+`
+
+func main() {
+ fmt.Println("package main")
+ ntypes := []string{
+ "byte", "rune", "uintptr",
+ "float32", "float64",
+ "int", "int8", "int16", "int32", "int64",
+ "uint", "uint8", "uint16", "uint32", "uint64",
+ }
+ for i, from := range ntypes {
+ for _, to := range ntypes[i:] {
+ fmt.Printf(tpl, from, to, from)
+ }
+ }
+ fmt.Println("func main() {}")
+}
diff --git a/test/fixedbugs/issue7346.go b/test/fixedbugs/issue7346.go
new file mode 100644
index 000000000..dd5ea222f
--- /dev/null
+++ b/test/fixedbugs/issue7346.go
@@ -0,0 +1,14 @@
+// compile
+
+// Copyright 2014 The Go 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 7346 : internal error "doasm" error due to checknil
+// of a nil literal.
+
+package main
+
+func main() {
+ _ = *(*int)(nil)
+}
diff --git a/test/fixedbugs/issue7366.go b/test/fixedbugs/issue7366.go
new file mode 100644
index 000000000..754da6fa2
--- /dev/null
+++ b/test/fixedbugs/issue7366.go
@@ -0,0 +1,21 @@
+// compile
+
+// Copyright 2014 The Go 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 7366: generates a temporary with ideal type
+// during comparison of small structs.
+
+package main
+
+type T struct {
+ data [10]byte
+}
+
+func main() {
+ var a T
+ var b T
+ if a == b {
+ }
+}
diff --git a/test/fixedbugs/issue7405.go b/test/fixedbugs/issue7405.go
new file mode 100644
index 000000000..52e1176c1
--- /dev/null
+++ b/test/fixedbugs/issue7405.go
@@ -0,0 +1,51 @@
+// compile
+
+// Copyright 2014 The Go 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 7405: the equality function for struct with many
+// embedded fields became more complex after fixing issue 7366,
+// leading to out of registers on 386.
+
+package p
+
+type T1 struct {
+ T2
+ T3
+ T4
+}
+
+type T2 struct {
+ Conn
+}
+
+type T3 struct {
+ PacketConn
+}
+
+type T4 struct {
+ PacketConn
+ T5
+}
+
+type T5 struct {
+ x int
+ T6
+}
+
+type T6 struct {
+ y, z int
+}
+
+type Conn interface {
+ A()
+}
+
+type PacketConn interface {
+ B()
+}
+
+func F(a, b T1) bool {
+ return a == b
+}
diff --git a/test/fixedbugs/issue7419.go b/test/fixedbugs/issue7419.go
new file mode 100644
index 000000000..39b454c05
--- /dev/null
+++ b/test/fixedbugs/issue7419.go
@@ -0,0 +1,25 @@
+// run
+
+// Copyright 2014 The Go 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 7419: odd behavior for float constants underflowing to 0
+
+package main
+
+import (
+ "os"
+)
+
+var x = 1e-779137
+var y = 1e-779138
+
+func main() {
+ if x != 0 {
+ os.Exit(1)
+ }
+ if y != 0 {
+ os.Exit(2)
+ }
+}
diff --git a/test/fixedbugs/issue7525.go b/test/fixedbugs/issue7525.go
new file mode 100644
index 000000000..4e1d88aab
--- /dev/null
+++ b/test/fixedbugs/issue7525.go
@@ -0,0 +1,19 @@
+// errorcheck
+
+// Copyright 2014 The Go 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 7525: self-referential array types.
+
+package main
+
+import "unsafe"
+
+var x struct {
+ a [unsafe.Sizeof(x.a)]int // ERROR "array bound|typechecking loop|invalid expression"
+ b [unsafe.Offsetof(x.b)]int // ERROR "array bound"
+ c [unsafe.Alignof(x.c)]int // ERROR "array bound|invalid expression"
+ d [len(x.d)]int // ERROR "array bound|invalid array"
+ e [cap(x.e)]int // ERROR "array bound|invalid array"
+}
diff --git a/test/fixedbugs/issue7538a.go b/test/fixedbugs/issue7538a.go
new file mode 100644
index 000000000..283d9eb1b
--- /dev/null
+++ b/test/fixedbugs/issue7538a.go
@@ -0,0 +1,15 @@
+// errorcheck
+
+// Copyright 2014 The Go 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 7538: blank (_) labels handled incorrectly
+
+package p
+
+func f() {
+_:
+_:
+ goto _ // ERROR "not defined"
+}
diff --git a/test/fixedbugs/issue7538b.go b/test/fixedbugs/issue7538b.go
new file mode 100644
index 000000000..28cef5d60
--- /dev/null
+++ b/test/fixedbugs/issue7538b.go
@@ -0,0 +1,13 @@
+// compile
+
+// Copyright 2014 The Go 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 7538: blank (_) labels handled incorrectly
+
+package p
+
+func f() {
+_:
+}
diff --git a/test/fixedbugs/issue7547.go b/test/fixedbugs/issue7547.go
new file mode 100644
index 000000000..f75a33036
--- /dev/null
+++ b/test/fixedbugs/issue7547.go
@@ -0,0 +1,17 @@
+// compile
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func f() map[string]interface{} {
+ var p *map[string]map[string]interface{}
+ _ = p
+ return nil
+}
+
+func main() {
+ f()
+}
diff --git a/test/fixedbugs/issue7550.go b/test/fixedbugs/issue7550.go
new file mode 100644
index 000000000..0c4cf9307
--- /dev/null
+++ b/test/fixedbugs/issue7550.go
@@ -0,0 +1,27 @@
+// run
+
+// Copyright 2014 The Go 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 shouldPanic(f func()) {
+ defer func() {
+ if recover() == nil {
+ panic("not panicking")
+ }
+ }()
+ f()
+}
+
+func f() {
+ length := int(^uint(0) >> 1)
+ a := make([]struct{}, length)
+ b := make([]struct{}, length)
+ _ = append(a, b...)
+}
+
+func main() {
+ shouldPanic(f)
+}
diff --git a/test/fixedbugs/issue7590.go b/test/fixedbugs/issue7590.go
new file mode 100644
index 000000000..e283832c3
--- /dev/null
+++ b/test/fixedbugs/issue7590.go
@@ -0,0 +1,21 @@
+// compile
+
+// Copyright 2014 The Go 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 7590: gccgo incorrectly traverses nested composite literals.
+
+package p
+
+type S struct {
+ F int
+}
+
+var M = map[string]S{
+ "a": { F: 1 },
+}
+
+var P = M["a"]
+
+var F = P.F
diff --git a/test/fixedbugs/issue7648.dir/a.go b/test/fixedbugs/issue7648.dir/a.go
new file mode 100644
index 000000000..c76aaa675
--- /dev/null
+++ b/test/fixedbugs/issue7648.dir/a.go
@@ -0,0 +1,11 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+const (
+ sinPi4 = 0.70710678118654752440084436210484903928483593768847
+ A = complex(sinPi4, -sinPi4)
+)
+
diff --git a/test/fixedbugs/issue7648.dir/b.go b/test/fixedbugs/issue7648.dir/b.go
new file mode 100644
index 000000000..b9223ed4e
--- /dev/null
+++ b/test/fixedbugs/issue7648.dir/b.go
@@ -0,0 +1,11 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package b
+
+import "a"
+
+func f() {
+ println(a.A)
+}
diff --git a/test/fixedbugs/issue7648.go b/test/fixedbugs/issue7648.go
new file mode 100644
index 000000000..b391c4a31
--- /dev/null
+++ b/test/fixedbugs/issue7648.go
@@ -0,0 +1,9 @@
+// compiledir
+
+// Copyright 2014 The Go 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 7648: spurious "bad negated constant" for complex constants.
+
+package ignored
diff --git a/test/fixedbugs/issue7675.go b/test/fixedbugs/issue7675.go
new file mode 100644
index 000000000..d97ee357a
--- /dev/null
+++ b/test/fixedbugs/issue7675.go
@@ -0,0 +1,24 @@
+// errorcheck
+
+// Copyright 2014 The Go 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 7675: fewer errors for wrong argument count
+
+package p
+
+func f(string, int, float64, string)
+
+func g(string, int, float64, ...string)
+
+func main() {
+ f(1, 0.5, "hello") // ERROR "not enough arguments"
+ f("1", 2, 3.1, "4")
+ f(1, 0.5, "hello", 4, 5) // ERROR "too many arguments"
+ g(1, 0.5) // ERROR "not enough arguments"
+ g("1", 2, 3.1)
+ g(1, 0.5, []int{3, 4}...) // ERROR "not enough arguments"
+ g("1", 2, 3.1, "4", "5")
+ g(1, 0.5, "hello", 4, []int{5, 6}...) // ERROR "too many arguments"
+}
diff --git a/test/fixedbugs/issue7742.go b/test/fixedbugs/issue7742.go
new file mode 100644
index 000000000..dc167c22e
--- /dev/null
+++ b/test/fixedbugs/issue7742.go
@@ -0,0 +1,18 @@
+// compile
+
+// Copyright 2014 The Go 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 7742: cannot use &autotmp_0001 (type *map[string]string) as type *string in function argument
+
+package main
+
+var (
+ m map[string]string
+ v string
+)
+
+func main() {
+ m[v], _ = v, v
+}
diff --git a/test/fixedbugs/issue7794.go b/test/fixedbugs/issue7794.go
new file mode 100644
index 000000000..1e303bd4f
--- /dev/null
+++ b/test/fixedbugs/issue7794.go
@@ -0,0 +1,12 @@
+// compile
+
+// Copyright 2014 The Go 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 [10]int
+ const ca = len(a)
+}
diff --git a/test/fixedbugs/issue7863.go b/test/fixedbugs/issue7863.go
new file mode 100644
index 000000000..97f225535
--- /dev/null
+++ b/test/fixedbugs/issue7863.go
@@ -0,0 +1,60 @@
+// run
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "fmt"
+)
+
+type Foo int64
+
+func (f *Foo) F() int64 {
+ return int64(*f)
+}
+
+type Bar int64
+
+func (b Bar) F() int64 {
+ return int64(b)
+}
+
+type Baz int32
+
+func (b Baz) F() int64 {
+ return int64(b)
+}
+
+func main() {
+ foo := Foo(123)
+ f := foo.F
+ if foo.F() != f() {
+ bug()
+ fmt.Println("foo.F", foo.F(), f())
+ }
+ bar := Bar(123)
+ f = bar.F
+ if bar.F() != f() {
+ bug()
+ fmt.Println("bar.F", bar.F(), f()) // duh!
+ }
+
+ baz := Baz(123)
+ f = baz.F
+ if baz.F() != f() {
+ bug()
+ fmt.Println("baz.F", baz.F(), f())
+ }
+}
+
+var bugged bool
+
+func bug() {
+ if !bugged {
+ bugged = true
+ fmt.Println("BUG")
+ }
+}
diff --git a/test/fixedbugs/issue7867.go b/test/fixedbugs/issue7867.go
new file mode 100644
index 000000000..9f28a7144
--- /dev/null
+++ b/test/fixedbugs/issue7867.go
@@ -0,0 +1,43 @@
+// runoutput
+
+// Copyright 2014 The Go 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 7867.
+
+package main
+
+import "fmt"
+
+const tpl = `
+func Test%d(t %s) {
+ _ = t
+ _ = t
+}
+`
+
+func main() {
+ fmt.Println("package main")
+ types := []string{
+ // These types always passed
+ "bool", "int", "rune",
+ "*int", "uintptr",
+ "float32", "float64",
+ "chan struct{}",
+ "map[string]struct{}",
+ "func()", "func(string)error",
+
+ // These types caused compilation failures
+ "complex64", "complex128",
+ "struct{}", "struct{n int}", "struct{e error}", "struct{m map[string]string}",
+ "string",
+ "[4]byte",
+ "[]byte",
+ "interface{}", "error",
+ }
+ for i, typ := range types {
+ fmt.Printf(tpl, i, typ)
+ }
+ fmt.Println("func main() {}")
+}
diff --git a/test/fixedbugs/issue7884.go b/test/fixedbugs/issue7884.go
new file mode 100644
index 000000000..497e26113
--- /dev/null
+++ b/test/fixedbugs/issue7884.go
@@ -0,0 +1,15 @@
+// compile
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "fmt"
+
+func main() {
+ var ii interface{} = 5
+ zz, err := ii.(interface{})
+ fmt.Println(zz, err)
+}
diff --git a/test/fixedbugs/issue7944.go b/test/fixedbugs/issue7944.go
new file mode 100644
index 000000000..9e5bed1a1
--- /dev/null
+++ b/test/fixedbugs/issue7944.go
@@ -0,0 +1,40 @@
+// run
+
+// Copyright 2014 The Go 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 7944:
+// Liveness bitmaps said b was live at call to g,
+// but no one told the register optimizer.
+
+package main
+
+import "runtime"
+
+func f(b []byte) {
+ for len(b) > 0 {
+ n := len(b)
+ n = f1(n)
+ f2(b[n:])
+ b = b[n:]
+ }
+ g()
+}
+
+func f1(n int) int {
+ runtime.GC()
+ return n
+}
+
+func f2(b []byte) {
+ runtime.GC()
+}
+
+func g() {
+ runtime.GC()
+}
+
+func main() {
+ f(make([]byte, 100))
+}
diff --git a/test/fixedbugs/issue7995.go b/test/fixedbugs/issue7995.go
new file mode 100644
index 000000000..05f116823
--- /dev/null
+++ b/test/fixedbugs/issue7995.go
@@ -0,0 +1,25 @@
+// run
+
+// Copyright 2014 The Go 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 7995: globals not flushed quickly enough.
+
+package main
+
+import "fmt"
+
+var (
+ p = 1
+ q = &p
+)
+
+func main() {
+ p = 50
+ *q = 100
+ s := fmt.Sprintln(p, *q)
+ if s != "100 100\n" {
+ println("BUG:", s)
+ }
+}
diff --git a/test/fixedbugs/issue7995b.dir/x1.go b/test/fixedbugs/issue7995b.dir/x1.go
new file mode 100644
index 000000000..075911b92
--- /dev/null
+++ b/test/fixedbugs/issue7995b.dir/x1.go
@@ -0,0 +1,16 @@
+package x1
+
+import "fmt"
+
+var P int
+
+var b bool
+
+func F(x *int) string {
+ if b { // avoid inlining
+ F(x)
+ }
+ P = 50
+ *x = 100
+ return fmt.Sprintln(P, *x)
+}
diff --git a/test/fixedbugs/issue7995b.dir/x2.go b/test/fixedbugs/issue7995b.dir/x2.go
new file mode 100644
index 000000000..eea23eabb
--- /dev/null
+++ b/test/fixedbugs/issue7995b.dir/x2.go
@@ -0,0 +1,10 @@
+package main
+
+import "./x1"
+
+func main() {
+ s := x1.F(&x1.P)
+ if s != "100 100\n" {
+ println("BUG:", s)
+ }
+}
diff --git a/test/fixedbugs/issue7995b.go b/test/fixedbugs/issue7995b.go
new file mode 100644
index 000000000..2f57371e3
--- /dev/null
+++ b/test/fixedbugs/issue7995b.go
@@ -0,0 +1,9 @@
+// rundir
+
+// Copyright 2014 The Go 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 7995: globals not flushed quickly enough.
+
+package ignored
diff --git a/test/fixedbugs/issue7996.go b/test/fixedbugs/issue7996.go
new file mode 100644
index 000000000..98289eb0c
--- /dev/null
+++ b/test/fixedbugs/issue7996.go
@@ -0,0 +1,14 @@
+// compile
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// /tmp/x.go:5: illegal constant expression: bool == interface {}
+
+package p
+
+var m = map[interface{}]struct{}{
+ nil: {},
+ true: {},
+}
diff --git a/test/fixedbugs/issue7997.go b/test/fixedbugs/issue7997.go
new file mode 100644
index 000000000..10c526273
--- /dev/null
+++ b/test/fixedbugs/issue7997.go
@@ -0,0 +1,53 @@
+// compile
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// /tmp/x.go:3: internal error: f &p (type *int) recorded as live on entry
+
+package p
+
+func f(ch chan int) *int {
+ select {
+ case p1x := <-ch:
+ return &p1x
+ default:
+ // ok
+ }
+ select {
+ case p1 := <-ch:
+ return &p1
+ default:
+ // ok
+ }
+ select {
+ case p2 := <-ch:
+ return &p2
+ case p3 := <-ch:
+ return &p3
+ default:
+ // ok
+ }
+ select {
+ case p4, ok := <-ch:
+ if ok {
+ return &p4
+ }
+ default:
+ // ok
+ }
+ select {
+ case p5, ok := <-ch:
+ if ok {
+ return &p5
+ }
+ case p6, ok := <-ch:
+ if !ok {
+ return &p6
+ }
+ default:
+ // ok
+ }
+ return nil
+}
diff --git a/test/fixedbugs/issue7998.go b/test/fixedbugs/issue7998.go
new file mode 100644
index 000000000..245035ede
--- /dev/null
+++ b/test/fixedbugs/issue7998.go
@@ -0,0 +1,23 @@
+// compile
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// /tmp/x.go:5: cannot use _ as value
+
+package p
+
+func f(ch chan int) bool {
+ select {
+ case _, ok := <-ch:
+ return ok
+ }
+ _, ok := <-ch
+ _ = ok
+ select {
+ case _, _ = <-ch:
+ return true
+ }
+ return false
+}
diff --git a/test/fixedbugs/issue8004.go b/test/fixedbugs/issue8004.go
new file mode 100644
index 000000000..37e2fe066
--- /dev/null
+++ b/test/fixedbugs/issue8004.go
@@ -0,0 +1,59 @@
+// run
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "reflect"
+ "runtime"
+ "unsafe"
+)
+
+func main() {
+ test1()
+ test2()
+}
+
+func test1() {
+ var all []interface{}
+ for i := 0; i < 100; i++ {
+ p := new([]int)
+ *p = append(*p, 1, 2, 3, 4)
+ h := (*reflect.SliceHeader)(unsafe.Pointer(p))
+ all = append(all, h, p)
+ }
+ runtime.GC()
+ for i := 0; i < 100; i++ {
+ p := *all[2*i+1].(*[]int)
+ if p[0] != 1 || p[1] != 2 || p[2] != 3 || p[3] != 4 {
+ println("BUG test1: bad slice at index", i, p[0], p[1], p[2], p[3])
+ return
+ }
+ }
+}
+
+type T struct {
+ H *reflect.SliceHeader
+ P *[]int
+}
+
+func test2() {
+ var all []T
+ for i := 0; i < 100; i++ {
+ p := new([]int)
+ *p = append(*p, 1, 2, 3, 4)
+ h := (*reflect.SliceHeader)(unsafe.Pointer(p))
+ all = append(all, T{H: h}, T{P: p})
+ }
+ runtime.GC()
+ for i := 0; i < 100; i++ {
+ p := *all[2*i+1].P
+ if p[0] != 1 || p[1] != 2 || p[2] != 3 || p[3] != 4 {
+ println("BUG test2: bad slice at index", i, p[0], p[1], p[2], p[3])
+ return
+ }
+ }
+}
diff --git a/test/fixedbugs/issue8011.go b/test/fixedbugs/issue8011.go
new file mode 100644
index 000000000..b966174c0
--- /dev/null
+++ b/test/fixedbugs/issue8011.go
@@ -0,0 +1,18 @@
+// run
+
+// Copyright 2014 The Go 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() {
+ c := make(chan chan int, 1)
+ c1 := make(chan int, 1)
+ c1 <- 42
+ c <- c1
+ x := <-<-c
+ if x != 42 {
+ println("BUG:", x, "!= 42")
+ }
+}
diff --git a/test/fixedbugs/issue8028.go b/test/fixedbugs/issue8028.go
new file mode 100644
index 000000000..7ceb902d4
--- /dev/null
+++ b/test/fixedbugs/issue8028.go
@@ -0,0 +1,27 @@
+// compile
+
+// Copyright 2014 The Go 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 8028. Used to fail in -race mode with "non-orig name" error.
+
+package p
+
+var (
+ t2 = T{F, "s1"}
+ t1 = T{F, "s2"}
+
+ tt = [...]T{t1, t2}
+)
+
+type I interface{}
+
+type T struct {
+ F func() I
+ S string
+}
+
+type E struct{}
+
+func F() I { return new(E) }
diff --git a/test/fixedbugs/issue8036.go b/test/fixedbugs/issue8036.go
new file mode 100644
index 000000000..f32fde84a
--- /dev/null
+++ b/test/fixedbugs/issue8036.go
@@ -0,0 +1,45 @@
+// run
+
+// Copyright 2014 The Go 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 8036. Stores necessary for stack scan being eliminated as redundant by optimizer.
+
+package main
+
+import "runtime"
+
+type T struct {
+ X *int
+ Y *int
+ Z *int
+}
+
+type TI [3]uintptr
+
+func G() (t TI) {
+ t[0] = 1
+ t[1] = 2
+ t[2] = 3
+ runtime.GC() // prevent inlining
+ return
+}
+
+func F() (t T) {
+ t.X = newint()
+ t.Y = t.X
+ t.Z = t.Y
+ runtime.GC() // prevent inlining
+ return
+}
+
+func newint() *int {
+ runtime.GC()
+ return nil
+}
+
+func main() {
+ G() // leave non-pointers where F's return values go
+ F()
+}
diff --git a/test/fixedbugs/issue8039.go b/test/fixedbugs/issue8039.go
new file mode 100644
index 000000000..b13e474d9
--- /dev/null
+++ b/test/fixedbugs/issue8039.go
@@ -0,0 +1,23 @@
+// run
+
+// Copyright 2014 The Go 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 8039. defer copy(x, <-c) did not rewrite <-c properly.
+
+package main
+
+func f(s []int) {
+ c := make(chan []int, 1)
+ c <- []int{1}
+ defer copy(s, <-c)
+}
+
+func main() {
+ x := make([]int, 1)
+ f(x)
+ if x[0] != 1 {
+ println("BUG", x[0])
+ }
+}
diff --git a/test/fixedbugs/issue8047.go b/test/fixedbugs/issue8047.go
new file mode 100644
index 000000000..fe7ada5c0
--- /dev/null
+++ b/test/fixedbugs/issue8047.go
@@ -0,0 +1,29 @@
+// run
+
+// Copyright 2014 The Go 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 8047. Stack copier shouldn't crash if there
+// is a nil defer.
+
+package main
+
+func stackit(n int) {
+ if n == 0 {
+ return
+ }
+ stackit(n - 1)
+}
+
+func main() {
+ defer func() {
+ // catch & ignore panic from nil defer below
+ err := recover()
+ if err == nil {
+ panic("defer of nil func didn't panic")
+ }
+ }()
+ defer ((func())(nil))()
+ stackit(1000)
+}
diff --git a/test/fixedbugs/issue8047b.go b/test/fixedbugs/issue8047b.go
new file mode 100644
index 000000000..de6acaab5
--- /dev/null
+++ b/test/fixedbugs/issue8047b.go
@@ -0,0 +1,22 @@
+// run
+
+// Copyright 2014 The Go 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 8047. Defer setup during panic shouldn't crash for nil defer.
+
+package main
+
+func main() {
+ defer func() {
+ recover()
+ }()
+ f()
+}
+
+func f() {
+ var g func()
+ defer g()
+ panic(1)
+}
diff --git a/test/fixedbugs/issue8048.go b/test/fixedbugs/issue8048.go
new file mode 100644
index 000000000..a7984c45a
--- /dev/null
+++ b/test/fixedbugs/issue8048.go
@@ -0,0 +1,107 @@
+// run
+
+// Copyright 2014 The Go 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 8048. Incorrect handling of liveness when walking stack
+// containing faulting frame.
+
+package main
+
+import "runtime"
+
+func main() {
+ test1()
+ test2()
+ test3()
+}
+
+func test1() {
+ // test1f will panic without its own defer.
+ // The runtime.GC checks that we can walk the stack
+ // at that point and not get confused.
+ // The recover lets test1 exit normally.
+ defer func() {
+ runtime.GC()
+ recover()
+ }()
+ test1f()
+}
+
+func test1f() {
+ // Because b == false, the if does not execute,
+ // so x == nil, so the println(*x) faults reading
+ // from nil. The compiler will lay out the code
+ // so that the if body occurs above the *x,
+ // so if the liveness info at the *x is used, it will
+ // find the liveness at the call to runtime.GC.
+ // It will think y is live, but y is uninitialized,
+ // and the runtime will crash detecting a bad slice.
+ // The runtime should see that there are no defers
+ // corresponding to this panicked frame and ignore
+ // the frame entirely.
+ var x *int
+ var b bool
+ if b {
+ y := make([]int, 1)
+ runtime.GC()
+ x = &y[0]
+ }
+ println(*x)
+}
+
+func test2() {
+ // Same as test1, but the fault happens in the function with the defer.
+ // The runtime should see the defer and garbage collect the frame
+ // as if the PC were immediately after the defer statement.
+ defer func() {
+ runtime.GC()
+ recover()
+ }()
+ var x *int
+ var b bool
+ if b {
+ y := make([]int, 1)
+ runtime.GC()
+ x = &y[0]
+ }
+ println(*x)
+}
+
+func test3() {
+ // Like test1 but avoid array index, which does not
+ // move to end of function on ARM.
+ defer func() {
+ runtime.GC()
+ recover()
+ }()
+ test3setup()
+ test3f()
+}
+
+func test3setup() {
+ var x uintptr
+ var b bool
+ b = true
+ if b {
+ y := uintptr(123)
+ runtime.GC()
+ x = y
+ }
+ runtime.GC()
+ globl = x
+}
+
+var globl uintptr
+
+func test3f() {
+ var x *int
+ var b bool
+ if b {
+ y := new(int)
+ runtime.GC()
+ x = y
+ }
+ println(*x)
+}
diff --git a/test/fixedbugs/issue8073.go b/test/fixedbugs/issue8073.go
new file mode 100644
index 000000000..660122110
--- /dev/null
+++ b/test/fixedbugs/issue8073.go
@@ -0,0 +1,15 @@
+// compile
+
+// Copyright 2014 The Go 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 8073.
+// was "internal compiler error: overflow: float64 integer constant"
+
+package main
+
+func main() {
+ var x int
+ _ = float64(x * 0)
+}
diff --git a/test/fixedbugs/issue8076.go b/test/fixedbugs/issue8076.go
new file mode 100644
index 000000000..ad8906775
--- /dev/null
+++ b/test/fixedbugs/issue8076.go
@@ -0,0 +1,17 @@
+// compile
+
+// Copyright 2014 The Go 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 8076. nilwalkfwd walked forward forever
+// on the instruction loop following the dereference.
+
+package main
+
+func main() {
+ _ = *(*int)(nil)
+L:
+ _ = 0
+ goto L
+}
diff --git a/test/fixedbugs/issue8132.go b/test/fixedbugs/issue8132.go
new file mode 100644
index 000000000..52f5d39c2
--- /dev/null
+++ b/test/fixedbugs/issue8132.go
@@ -0,0 +1,32 @@
+// run
+
+// Copyright 2014 The Go 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 8132. stack walk handling of panic stack was confused
+// about what was legal.
+
+package main
+
+import "runtime"
+
+var p *int
+
+func main() {
+ func() {
+ defer func() {
+ runtime.GC()
+ recover()
+ }()
+ var x [8192]byte
+ func(x [8192]byte) {
+ defer func() {
+ if err := recover(); err != nil {
+ println(*p)
+ }
+ }()
+ println(*p)
+ }(x)
+ }()
+}
diff --git a/test/fixedbugs/issue8139.go b/test/fixedbugs/issue8139.go
new file mode 100644
index 000000000..821c9ff65
--- /dev/null
+++ b/test/fixedbugs/issue8139.go
@@ -0,0 +1,50 @@
+// run
+
+// Copyright 2014 The Go 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 8139. The x.(T) assertions used to write 1 (unexpected)
+// return byte for the 0-byte return value T.
+
+package main
+
+import "fmt"
+
+type T struct{}
+
+func (T) M() {}
+
+type M interface {
+ M()
+}
+
+var e interface{} = T{}
+var i M = T{}
+var b bool
+
+func f1() int {
+ if b {
+ return f1() // convince inliner not to inline
+ }
+ z := 0x11223344
+ _ = e.(T)
+ return z
+}
+
+func f2() int {
+ if b {
+ return f1() // convince inliner not to inline
+ }
+ z := 0x11223344
+ _ = i.(T)
+ return z
+}
+
+func main() {
+ x := f1()
+ y := f2()
+ if x != 0x11223344 || y != 0x11223344 {
+ fmt.Printf("BUG: x=%#x y=%#x, want 0x11223344 for both\n", x, y)
+ }
+}
diff --git a/test/fixedbugs/issue8155.go b/test/fixedbugs/issue8155.go
new file mode 100644
index 000000000..c611f6cb1
--- /dev/null
+++ b/test/fixedbugs/issue8155.go
@@ -0,0 +1,48 @@
+// run
+
+// Copyright 2014 The Go 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 8155.
+// Alignment of stack prologue zeroing was wrong on 64-bit Native Client
+// (because of 32-bit pointers).
+
+package main
+
+import "runtime"
+
+func bad(b bool) uintptr {
+ var p **int
+ var x1 uintptr
+ x1 = 1
+ if b {
+ var x [11]*int
+ p = &x[0]
+ }
+ if b {
+ var x [1]*int
+ p = &x[0]
+ }
+ runtime.GC()
+ if p != nil {
+ x1 = uintptr(**p)
+ }
+ return x1
+}
+
+func poison() uintptr {
+ runtime.GC()
+ var x [20]uintptr
+ var s uintptr
+ for i := range x {
+ x[i] = uintptr(i+1)
+ s += x[i]
+ }
+ return s
+}
+
+func main() {
+ poison()
+ bad(false)
+}
diff --git a/test/fixedbugs/issue8158.go b/test/fixedbugs/issue8158.go
new file mode 100644
index 000000000..b110de11f
--- /dev/null
+++ b/test/fixedbugs/issue8158.go
@@ -0,0 +1,41 @@
+// run
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "runtime"
+ "time"
+)
+
+func main() {
+ c := make(chan bool, 1)
+ go f1(c)
+ <-c
+ time.Sleep(10 * time.Millisecond)
+ go f2(c)
+ <-c
+}
+
+func f1(done chan bool) {
+ defer func() {
+ recover()
+ done <- true
+ runtime.Goexit() // left stack-allocated Panic struct on gp->panic stack
+ }()
+ panic("p")
+}
+
+func f2(done chan bool) {
+ defer func() {
+ recover()
+ done <- true
+ runtime.Goexit()
+ }()
+ time.Sleep(10 * time.Millisecond) // overwrote Panic struct with Timer struct
+ runtime.GC() // walked gp->panic list, found mangled Panic struct, crashed
+ panic("p")
+}
diff --git a/test/float_lit2.go b/test/float_lit2.go
new file mode 100644
index 000000000..96d23f38d
--- /dev/null
+++ b/test/float_lit2.go
@@ -0,0 +1,164 @@
+// run
+
+// Check conversion of constant to float32/float64 near min/max boundaries.
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "fmt"
+ "math"
+)
+
+// The largest exact float32 is f₁ = (1+(1-2²³))×2¹²⁷ = (1-2²⁴)×2¹²⁸ = 2¹²⁸ - 2¹⁰⁴.
+// The next float32 would be f₂ = (1+1)×2¹²⁷ = 1×2¹²⁸, except that exponent is out of range.
+// Float32 conversion rounds to the nearest float32, rounding to even mantissa:
+// between f₁ and f₂, values closer to f₁ round to f₁ and values closer to f₂ are rejected as out of range.
+// f₁ is an odd mantissa, so the halfway point (f₁+f₂)/2 rounds to f₂ and is rejected.
+// The halfway point is (f₁+f₂)/2 = 2¹²⁸ - 2¹⁰⁵.
+//
+// The same is true of float64, with different constants: s/24/53/ and s/128/1024/.
+
+const (
+ two24 = 1.0 * (1 << 24)
+ two53 = 1.0 * (1 << 53)
+ two64 = 1.0 * (1 << 64)
+ two128 = two64 * two64
+ two256 = two128 * two128
+ two512 = two256 * two256
+ two768 = two512 * two256
+ two1024 = two512 * two512
+
+ ulp32 = two128 / two24
+ max32 = two128 - ulp32
+
+ ulp64 = two1024 / two53
+ max64 = two1024 - ulp64
+)
+
+var cvt = []struct {
+ bits uint64 // keep us honest
+ exact interface{}
+ approx interface{}
+ text string
+}{
+ // 0
+ {0x7f7ffffe, float32(max32 - ulp32), float32(max32 - ulp32 - ulp32/2), "max32 - ulp32 - ulp32/2"},
+ {0x7f7ffffe, float32(max32 - ulp32), float32(max32 - ulp32), "max32 - ulp32"},
+ {0x7f7ffffe, float32(max32 - ulp32), float32(max32 - ulp32/2), "max32 - ulp32/2"},
+ {0x7f7ffffe, float32(max32 - ulp32), float32(max32 - ulp32 + ulp32/2), "max32 - ulp32 + ulp32/2"},
+ {0x7f7fffff, float32(max32), float32(max32 - ulp32 + ulp32/2 + ulp32/two64), "max32 - ulp32 + ulp32/2 + ulp32/two64"},
+ {0x7f7fffff, float32(max32), float32(max32 - ulp32/2 + ulp32/two64), "max32 - ulp32/2 + ulp32/two64"},
+ {0x7f7fffff, float32(max32), float32(max32), "max32"},
+ {0x7f7fffff, float32(max32), float32(max32 + ulp32/2 - ulp32/two64), "max32 + ulp32/2 - ulp32/two64"},
+
+ {0xff7ffffe, float32(-(max32 - ulp32)), float32(-(max32 - ulp32 - ulp32/2)), "-(max32 - ulp32 - ulp32/2)"},
+ {0xff7ffffe, float32(-(max32 - ulp32)), float32(-(max32 - ulp32)), "-(max32 - ulp32)"},
+ {0xff7ffffe, float32(-(max32 - ulp32)), float32(-(max32 - ulp32/2)), "-(max32 - ulp32/2)"},
+ {0xff7ffffe, float32(-(max32 - ulp32)), float32(-(max32 - ulp32 + ulp32/2)), "-(max32 - ulp32 + ulp32/2)"},
+ {0xff7fffff, float32(-(max32)), float32(-(max32 - ulp32 + ulp32/2 + ulp32/two64)), "-(max32 - ulp32 + ulp32/2 + ulp32/two64)"},
+ {0xff7fffff, float32(-(max32)), float32(-(max32 - ulp32/2 + ulp32/two64)), "-(max32 - ulp32/2 + ulp32/two64)"},
+ {0xff7fffff, float32(-(max32)), float32(-(max32)), "-(max32)"},
+ {0xff7fffff, float32(-(max32)), float32(-(max32 + ulp32/2 - ulp32/two64)), "-(max32 + ulp32/2 - ulp32/two64)"},
+
+ // These are required to work: according to the Go spec, the internal float mantissa must be at least 256 bits,
+ // and these expressions can be represented exactly with a 256-bit mantissa.
+ {0x7f7fffff, float32(max32), float32(max32 - ulp32 + ulp32/2 + 1), "max32 - ulp32 + ulp32/2 + 1"},
+ {0x7f7fffff, float32(max32), float32(max32 - ulp32/2 + 1), "max32 - ulp32/2 + 1"},
+ {0x7f7fffff, float32(max32), float32(max32 + ulp32/2 - 1), "max32 + ulp32/2 - 1"},
+ {0xff7fffff, float32(-(max32)), float32(-(max32 - ulp32 + ulp32/2 + 1)), "-(max32 - ulp32 + ulp32/2 + 1)"},
+ {0xff7fffff, float32(-(max32)), float32(-(max32 - ulp32/2 + 1)), "-(max32 - ulp32/2 + 1)"},
+ {0xff7fffff, float32(-(max32)), float32(-(max32 + ulp32/2 - 1)), "-(max32 + ulp32/2 - 1)"},
+
+ {0x7f7fffff, float32(max32), float32(max32 - ulp32 + ulp32/2 + 1/two128), "max32 - ulp32 + ulp32/2 + 1/two128"},
+ {0x7f7fffff, float32(max32), float32(max32 - ulp32/2 + 1/two128), "max32 - ulp32/2 + 1/two128"},
+ {0x7f7fffff, float32(max32), float32(max32 + ulp32/2 - 1/two128), "max32 + ulp32/2 - 1/two128"},
+ {0xff7fffff, float32(-(max32)), float32(-(max32 - ulp32 + ulp32/2 + 1/two128)), "-(max32 - ulp32 + ulp32/2 + 1/two128)"},
+ {0xff7fffff, float32(-(max32)), float32(-(max32 - ulp32/2 + 1/two128)), "-(max32 - ulp32/2 + 1/two128)"},
+ {0xff7fffff, float32(-(max32)), float32(-(max32 + ulp32/2 - 1/two128)), "-(max32 + ulp32/2 - 1/two128)"},
+
+ {0x7feffffffffffffe, float64(max64 - ulp64), float64(max64 - ulp64 - ulp64/2), "max64 - ulp64 - ulp64/2"},
+ {0x7feffffffffffffe, float64(max64 - ulp64), float64(max64 - ulp64), "max64 - ulp64"},
+ {0x7feffffffffffffe, float64(max64 - ulp64), float64(max64 - ulp64/2), "max64 - ulp64/2"},
+ {0x7feffffffffffffe, float64(max64 - ulp64), float64(max64 - ulp64 + ulp64/2), "max64 - ulp64 + ulp64/2"},
+ {0x7fefffffffffffff, float64(max64), float64(max64 - ulp64 + ulp64/2 + ulp64/two64), "max64 - ulp64 + ulp64/2 + ulp64/two64"},
+ {0x7fefffffffffffff, float64(max64), float64(max64 - ulp64/2 + ulp64/two64), "max64 - ulp64/2 + ulp64/two64"},
+ {0x7fefffffffffffff, float64(max64), float64(max64), "max64"},
+ {0x7fefffffffffffff, float64(max64), float64(max64 + ulp64/2 - ulp64/two64), "max64 + ulp64/2 - ulp64/two64"},
+
+ {0xffeffffffffffffe, float64(-(max64 - ulp64)), float64(-(max64 - ulp64 - ulp64/2)), "-(max64 - ulp64 - ulp64/2)"},
+ {0xffeffffffffffffe, float64(-(max64 - ulp64)), float64(-(max64 - ulp64)), "-(max64 - ulp64)"},
+ {0xffeffffffffffffe, float64(-(max64 - ulp64)), float64(-(max64 - ulp64/2)), "-(max64 - ulp64/2)"},
+ {0xffeffffffffffffe, float64(-(max64 - ulp64)), float64(-(max64 - ulp64 + ulp64/2)), "-(max64 - ulp64 + ulp64/2)"},
+ {0xffefffffffffffff, float64(-(max64)), float64(-(max64 - ulp64 + ulp64/2 + ulp64/two64)), "-(max64 - ulp64 + ulp64/2 + ulp64/two64)"},
+ {0xffefffffffffffff, float64(-(max64)), float64(-(max64 - ulp64/2 + ulp64/two64)), "-(max64 - ulp64/2 + ulp64/two64)"},
+ {0xffefffffffffffff, float64(-(max64)), float64(-(max64)), "-(max64)"},
+ {0xffefffffffffffff, float64(-(max64)), float64(-(max64 + ulp64/2 - ulp64/two64)), "-(max64 + ulp64/2 - ulp64/two64)"},
+
+ // These are required to work.
+ // The mantissas are exactly 256 bits.
+ // max64 is just below 2¹⁰²⁴ so the bottom bit we can use is 2⁷⁶⁸.
+ {0x7fefffffffffffff, float64(max64), float64(max64 - ulp64 + ulp64/2 + two768), "max64 - ulp64 + ulp64/2 + two768"},
+ {0x7fefffffffffffff, float64(max64), float64(max64 - ulp64/2 + two768), "max64 - ulp64/2 + two768"},
+ {0x7fefffffffffffff, float64(max64), float64(max64 + ulp64/2 - two768), "max64 + ulp64/2 - two768"},
+ {0xffefffffffffffff, float64(-(max64)), float64(-(max64 - ulp64 + ulp64/2 + two768)), "-(max64 - ulp64 + ulp64/2 + two768)"},
+ {0xffefffffffffffff, float64(-(max64)), float64(-(max64 - ulp64/2 + two768)), "-(max64 - ulp64/2 + two768)"},
+ {0xffefffffffffffff, float64(-(max64)), float64(-(max64 + ulp64/2 - two768)), "-(max64 + ulp64/2 - two768)"},
+}
+
+var bugged = false
+
+func bug() {
+ if !bugged {
+ bugged = true
+ fmt.Println("BUG")
+ }
+}
+
+func main() {
+ u64 := math.Float64frombits(0x7fefffffffffffff) - math.Float64frombits(0x7feffffffffffffe)
+ if ulp64 != u64 {
+ bug()
+ fmt.Printf("ulp64=%g, want %g", ulp64, u64)
+ }
+
+ u32 := math.Float32frombits(0x7f7fffff) - math.Float32frombits(0x7f7ffffe)
+ if ulp32 != u32 {
+ bug()
+ fmt.Printf("ulp32=%g, want %g", ulp32, u32)
+ }
+
+ for _, c := range cvt {
+ if bits(c.exact) != c.bits {
+ bug()
+ fmt.Printf("%s: inconsistent table: bits=%#x (%g) but exact=%g (%#x)\n", c.text, c.bits, fromBits(c.bits, c.exact), c.exact, bits(c.exact))
+ }
+ if c.approx != c.exact || bits(c.approx) != c.bits {
+ bug()
+ fmt.Printf("%s: have %g (%#x) want %g (%#x)\n", c.text, c.approx, bits(c.approx), c.exact, c.bits)
+ }
+ }
+}
+
+func bits(x interface{}) interface{} {
+ switch x := x.(type) {
+ case float32:
+ return uint64(math.Float32bits(x))
+ case float64:
+ return math.Float64bits(x)
+ }
+ return 0
+}
+
+func fromBits(b uint64, x interface{}) interface{} {
+ switch x.(type) {
+ case float32:
+ return math.Float32frombits(uint32(b))
+ case float64:
+ return math.Float64frombits(b)
+ }
+ return "?"
+}
diff --git a/test/float_lit3.go b/test/float_lit3.go
new file mode 100644
index 000000000..43dca9cfa
--- /dev/null
+++ b/test/float_lit3.go
@@ -0,0 +1,48 @@
+// errorcheck
+
+// Check flagging of invalid conversion of constant to float32/float64 near min/max boundaries.
+
+// Copyright 2014 The Go 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
+
+// See float_lit2.go for motivation for these values.
+const (
+ two24 = 1.0 * (1 << 24)
+ two53 = 1.0 * (1 << 53)
+ two64 = 1.0 * (1 << 64)
+ two128 = two64 * two64
+ two256 = two128 * two128
+ two512 = two256 * two256
+ two768 = two512 * two256
+ two1024 = two512 * two512
+
+ ulp32 = two128 / two24
+ max32 = two128 - ulp32
+
+ ulp64 = two1024 / two53
+ max64 = two1024 - ulp64
+)
+
+var x = []interface{}{
+ float32(max32 + ulp32/2 - 1), // ok
+ float32(max32 + ulp32/2 - two128/two256), // ok
+ float32(max32 + ulp32/2), // ERROR "constant 3\.40282e\+38 overflows float32"
+
+ float32(-max32 - ulp32/2 + 1), // ok
+ float32(-max32 - ulp32/2 + two128/two256), // ok
+ float32(-max32 - ulp32/2), // ERROR "constant -3\.40282e\+38 overflows float32"
+
+ // If the compiler's internal floating point representation
+ // is shorter than 1024 bits, it cannot distinguish max64+ulp64/2-1 and max64+ulp64/2.
+ // gc uses fewer than 1024 bits, so allow it to print the overflow error for the -1 case.
+ float64(max64 + ulp64/2 - two1024/two256), // ok
+ float64(max64 + ulp64/2 - 1), // GC_ERROR "constant 1\.79769e\+308 overflows float64"
+ float64(max64 + ulp64/2), // ERROR "constant 1\.79769e\+308 overflows float64"
+
+ float64(-max64 - ulp64/2 + two1024/two256), // ok
+ float64(-max64 - ulp64/2 + 1), // GC_ERROR "constant -1\.79769e\+308 overflows float64"
+ float64(-max64 - ulp64/2), // ERROR "constant -1\.79769e\+308 overflows float64"
+}
diff --git a/test/funcdup.go b/test/funcdup.go
index 706dd63ca..d15d68579 100644
--- a/test/funcdup.go
+++ b/test/funcdup.go
@@ -7,21 +7,21 @@
package p
type T interface {
- F1(i int) (i int) // ERROR "duplicate argument i"
- F2(i, i int) // ERROR "duplicate argument i"
- F3() (i, i int) // ERROR "duplicate argument i"
+ F1(i int) (i int) // ERROR "duplicate argument i|redefinition|previous"
+ F2(i, i int) // ERROR "duplicate argument i|redefinition|previous"
+ F3() (i, i int) // ERROR "duplicate argument i|redefinition|previous"
}
-type T1 func(i, i int) // ERROR "duplicate argument i"
-type T2 func(i int) (i int) // ERROR "duplicate argument i"
-type T3 func() (i, i int) // ERROR "duplicate argument i"
+type T1 func(i, i int) // ERROR "duplicate argument i|redefinition|previous"
+type T2 func(i int) (i int) // ERROR "duplicate argument i|redefinition|previous"
+type T3 func() (i, i int) // ERROR "duplicate argument i|redefinition|previous"
type R struct{}
-func (i *R) F1(i int) {} // ERROR "duplicate argument i"
-func (i *R) F2() (i int) {return 0} // ERROR "duplicate argument i"
-func (i *R) F3(j int) (j int) {return 0} // ERROR "duplicate argument j"
+func (i *R) F1(i int) {} // ERROR "duplicate argument i|redefinition|previous"
+func (i *R) F2() (i int) {return 0} // ERROR "duplicate argument i|redefinition|previous"
+func (i *R) F3(j int) (j int) {return 0} // ERROR "duplicate argument j|redefinition|previous"
-func F1(i, i int) {} // ERROR "duplicate argument i"
-func F2(i int) (i int) {return 0} // ERROR "duplicate argument i"
-func F3() (i, i int) {return 0, 0} // ERROR "duplicate argument i"
+func F1(i, i int) {} // ERROR "duplicate argument i|redefinition|previous"
+func F2(i int) (i int) {return 0} // ERROR "duplicate argument i|redefinition|previous"
+func F3() (i, i int) {return 0, 0} // ERROR "duplicate argument i|redefinition|previous"
diff --git a/test/funcdup2.go b/test/funcdup2.go
index aeb5f7eb6..1db1a396b 100644
--- a/test/funcdup2.go
+++ b/test/funcdup2.go
@@ -7,11 +7,11 @@
package p
var T interface {
- F1(i int) (i int) // ERROR "duplicate argument i"
- F2(i, i int) // ERROR "duplicate argument i"
- F3() (i, i int) // ERROR "duplicate argument i"
+ F1(i int) (i int) // ERROR "duplicate argument i|redefinition|previous"
+ F2(i, i int) // ERROR "duplicate argument i|redefinition|previous"
+ F3() (i, i int) // ERROR "duplicate argument i|redefinition|previous"
}
-var T1 func(i, i int) // ERROR "duplicate argument i"
-var T2 func(i int) (i int) // ERROR "duplicate argument i"
-var T3 func() (i, i int) // ERROR "duplicate argument i"
+var T1 func(i, i int) // ERROR "duplicate argument i|redefinition|previous"
+var T2 func(i int) (i int) // ERROR "duplicate argument i|redefinition|previous"
+var T3 func() (i, i int) // ERROR "duplicate argument i|redefinition|previous"
diff --git a/test/gc2.go b/test/gc2.go
index de52a4fbf..561516b8b 100644
--- a/test/gc2.go
+++ b/test/gc2.go
@@ -1,5 +1,7 @@
// run
+// +build !nacl
+
// 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.
@@ -36,7 +38,7 @@ func main() {
}
runtime.ReadMemStats(memstats)
- obj := memstats.HeapObjects - st.HeapObjects
+ obj := int64(memstats.HeapObjects - st.HeapObjects)
if obj > N/5 {
fmt.Println("too many objects left:", obj)
os.Exit(1)
diff --git a/test/gcstring.go b/test/gcstring.go
new file mode 100644
index 000000000..627a42645
--- /dev/null
+++ b/test/gcstring.go
@@ -0,0 +1,48 @@
+// run
+
+// Copyright 2014 The Go 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 s[len(s):] - which can point past the end of the allocated block -
+// does not confuse the garbage collector.
+
+package main
+
+import (
+ "runtime"
+ "time"
+)
+
+type T struct {
+ ptr **int
+ pad [120]byte
+}
+
+var things []interface{}
+
+func main() {
+ setup()
+ runtime.GC()
+ runtime.GC()
+ time.Sleep(10*time.Millisecond)
+ runtime.GC()
+ runtime.GC()
+ time.Sleep(10*time.Millisecond)
+}
+
+func setup() {
+ var Ts []interface{}
+ buf := make([]byte, 128)
+
+ for i := 0; i < 10000; i++ {
+ s := string(buf)
+ t := &T{ptr: new(*int)}
+ runtime.SetFinalizer(t.ptr, func(**int) { panic("*int freed too early") })
+ Ts = append(Ts, t)
+ things = append(things, s[len(s):])
+ }
+
+ things = append(things, Ts...)
+}
+
diff --git a/test/import1.go b/test/import1.go
index d2bb55cbf..2433b5f2a 100644
--- a/test/import1.go
+++ b/test/import1.go
@@ -15,5 +15,5 @@ import bufio "os" // ERROR "redeclared|redefinition|incompatible" "imported and
import (
"fmt" // GCCGO_ERROR "previous|not used"
fmt "math" // ERROR "redeclared|redefinition|incompatible" "imported and not used: \x22math\x22 as fmt"
- . "math" // ERROR "imported and not used: \x22math\x22$"
+ . "math" // GC_ERROR "imported and not used: \x22math\x22$"
)
diff --git a/test/import4.dir/empty.go b/test/import4.dir/empty.go
index c8214f36d..1dffa170d 100644
--- a/test/import4.dir/empty.go
+++ b/test/import4.dir/empty.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-package P
+package empty
import ( )
const ( )
diff --git a/test/import4.dir/import4.go b/test/import4.dir/import4.go
index b9f973f17..f92c663d0 100644
--- a/test/import4.dir/import4.go
+++ b/test/import4.dir/import4.go
@@ -18,7 +18,7 @@ import X "math" // ERROR "imported and not used.*math"
import . "bufio" // ERROR "imported and not used.*bufio"
// again, package without anything in it
-import "./empty" // ERROR "imported and not used.*empty"
-import Z "./empty" // ERROR "imported and not used.*empty"
+import "./empty" // GC_ERROR "imported and not used.*empty"
+import Z "./empty" // GC_ERROR "imported and not used.*empty"
import . "./empty" // ERROR "imported and not used.*empty"
diff --git a/test/live.go b/test/live.go
new file mode 100644
index 000000000..b4cced47e
--- /dev/null
+++ b/test/live.go
@@ -0,0 +1,624 @@
+// errorcheck -0 -l -live
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// liveness tests with inlining disabled.
+// see also live2.go.
+
+package main
+
+func f1() {
+ var x *int
+ print(&x) // ERROR "live at call to printpointer: x$"
+ print(&x) // ERROR "live at call to printpointer: x$"
+}
+
+func f2(b bool) {
+ if b {
+ print(0) // nothing live here
+ return
+ }
+ var x *int
+ print(&x) // ERROR "live at call to printpointer: x$"
+ print(&x) // ERROR "live at call to printpointer: x$"
+}
+
+func f3(b bool) {
+ // Because x and y are ambiguously live, they appear
+ // live throughout the function, to avoid being poisoned
+ // in GODEBUG=gcdead=1 mode.
+
+ print(0) // ERROR "live at call to printint: x y$"
+ if b == false {
+ print(0) // ERROR "live at call to printint: x y$"
+ return
+ }
+
+ if b {
+ var x *int
+ print(&x) // ERROR "live at call to printpointer: x y$"
+ print(&x) // ERROR "live at call to printpointer: x y$"
+ } else {
+ var y *int
+ print(&y) // ERROR "live at call to printpointer: x y$"
+ print(&y) // ERROR "live at call to printpointer: x y$"
+ }
+ print(0) // ERROR "live at call to printint: x y$" "x \(type \*int\) is ambiguously live" "y \(type \*int\) is ambiguously live"
+}
+
+// The old algorithm treated x as live on all code that
+// could flow to a return statement, so it included the
+// function entry and code above the declaration of x
+// but would not include an indirect use of x in an infinite loop.
+// Check that these cases are handled correctly.
+
+func f4(b1, b2 bool) { // x not live here
+ if b2 {
+ print(0) // x not live here
+ return
+ }
+ var z **int
+ x := new(int)
+ *x = 42
+ z = &x
+ print(**z) // ERROR "live at call to printint: x z$"
+ if b2 {
+ print(1) // ERROR "live at call to printint: x$"
+ return
+ }
+ for {
+ print(**z) // ERROR "live at call to printint: x z$"
+ }
+}
+
+func f5(b1 bool) {
+ var z **int
+ if b1 {
+ x := new(int)
+ *x = 42
+ z = &x
+ } else {
+ y := new(int)
+ *y = 54
+ z = &y
+ }
+ print(**z) // ERROR "live at call to printint: x y$" "x \(type \*int\) is ambiguously live" "y \(type \*int\) is ambiguously live"
+}
+
+// confusion about the _ result used to cause spurious "live at entry to f6: _".
+
+func f6() (_, y string) {
+ y = "hello"
+ return
+}
+
+// confusion about addressed results used to cause "live at entry to f7: x".
+
+func f7() (x string) {
+ _ = &x
+ x = "hello"
+ return
+}
+
+// ignoring block returns used to cause "live at entry to f8: x, y".
+
+func f8() (x, y string) {
+ return g8()
+}
+
+func g8() (string, string)
+
+// ignoring block assignments used to cause "live at entry to f9: x"
+// issue 7205
+
+var i9 interface{}
+
+func f9() bool {
+ g8()
+ x := i9
+ return x != 99
+}
+
+// liveness formerly confused by UNDEF followed by RET,
+// leading to "live at entry to f10: ~r1" (unnamed result).
+
+func f10() string {
+ panic(1)
+}
+
+// liveness formerly confused by select, thinking runtime.selectgo
+// can return to next instruction; it always jumps elsewhere.
+// note that you have to use at least two cases in the select
+// to get a true select; smaller selects compile to optimized helper functions.
+
+var c chan *int
+var b bool
+
+// this used to have a spurious "live at entry to f11a: ~r0"
+func f11a() *int {
+ select { // ERROR "live at call to selectgo: autotmp"
+ case <-c: // ERROR "live at call to selectrecv: autotmp"
+ return nil
+ case <-c: // ERROR "live at call to selectrecv: autotmp"
+ return nil
+ }
+}
+
+func f11b() *int {
+ p := new(int)
+ if b {
+ // At this point p is dead: the code here cannot
+ // get to the bottom of the function.
+ // This used to have a spurious "live at call to printint: p".
+ print(1) // nothing live here!
+ select { // ERROR "live at call to selectgo: autotmp"
+ case <-c: // ERROR "live at call to selectrecv: autotmp"
+ return nil
+ case <-c: // ERROR "live at call to selectrecv: autotmp"
+ return nil
+ }
+ }
+ println(*p)
+ return nil
+}
+
+func f11c() *int {
+ p := new(int)
+ if b {
+ // Unlike previous, the cases in this select fall through,
+ // so we can get to the println, so p is not dead.
+ print(1) // ERROR "live at call to printint: p"
+ select { // ERROR "live at call to newselect: p" "live at call to selectgo: autotmp.* p"
+ case <-c: // ERROR "live at call to selectrecv: autotmp.* p"
+ case <-c: // ERROR "live at call to selectrecv: autotmp.* p"
+ }
+ }
+ println(*p)
+ return nil
+}
+
+// similarly, select{} does not fall through.
+// this used to have a spurious "live at entry to f12: ~r0".
+
+func f12() *int {
+ if b {
+ select{}
+ } else {
+ return nil
+ }
+}
+
+// incorrectly placed VARDEF annotations can cause missing liveness annotations.
+// this used to be missing the fact that s is live during the call to g13 (because it is
+// needed for the call to h13).
+
+func f13() {
+ s := "hello"
+ s = h13(s, g13(s)) // ERROR "live at call to g13: s"
+}
+
+func g13(string) string
+func h13(string, string) string
+
+// more incorrectly placed VARDEF.
+
+func f14() {
+ x := g14()
+ print(&x) // ERROR "live at call to printpointer: x"
+}
+
+func g14() string
+
+func f15() {
+ var x string
+ _ = &x
+ x = g15() // ERROR "live at call to g15: x"
+ print(x) // ERROR "live at call to printstring: x"
+}
+
+func g15() string
+
+// Checking that various temporaries do not persist or cause
+// ambiguously live values that must be zeroed.
+// The exact temporary names are inconsequential but we are
+// trying to check that there is only one at any given site,
+// and also that none show up in "ambiguously live" messages.
+
+var m map[string]int
+
+func f16() {
+ if b {
+ delete(m, "hi") // ERROR "live at call to mapdelete: autotmp_[0-9]+$"
+ }
+ delete(m, "hi") // ERROR "live at call to mapdelete: autotmp_[0-9]+$"
+ delete(m, "hi") // ERROR "live at call to mapdelete: autotmp_[0-9]+$"
+}
+
+var m2s map[string]*byte
+var m2 map[[2]string]*byte
+var x2 [2]string
+var bp *byte
+
+func f17a() {
+ // value temporary only
+ if b {
+ m2[x2] = nil // ERROR "live at call to mapassign1: autotmp_[0-9]+$"
+ }
+ m2[x2] = nil // ERROR "live at call to mapassign1: autotmp_[0-9]+$"
+ m2[x2] = nil // ERROR "live at call to mapassign1: autotmp_[0-9]+$"
+}
+
+func f17b() {
+ // key temporary only
+ if b {
+ m2s["x"] = bp // ERROR "live at call to mapassign1: autotmp_[0-9]+$"
+ }
+ m2s["x"] = bp // ERROR "live at call to mapassign1: autotmp_[0-9]+$"
+ m2s["x"] = bp // ERROR "live at call to mapassign1: autotmp_[0-9]+$"
+}
+
+func f17c() {
+ // key and value temporaries
+ if b {
+ m2s["x"] = nil // ERROR "live at call to mapassign1: autotmp_[0-9]+ autotmp_[0-9]+$"
+ }
+ m2s["x"] = nil // ERROR "live at call to mapassign1: autotmp_[0-9]+ autotmp_[0-9]+$"
+ m2s["x"] = nil // ERROR "live at call to mapassign1: autotmp_[0-9]+ autotmp_[0-9]+$"
+}
+
+func g18() [2]string
+
+func f18() {
+ // key temporary for mapaccess.
+ // temporary introduced by orderexpr.
+ var z *byte
+ if b {
+ z = m2[g18()] // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
+ }
+ z = m2[g18()] // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
+ z = m2[g18()] // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
+ print(z)
+}
+
+var ch chan *byte
+
+func f19() {
+ // dest temporary for channel receive.
+ var z *byte
+
+ if b {
+ z = <-ch // ERROR "live at call to chanrecv1: autotmp_[0-9]+$"
+ }
+ z = <-ch // ERROR "live at call to chanrecv1: autotmp_[0-9]+$"
+ z = <-ch // ERROR "live at call to chanrecv1: autotmp_[0-9]+$"
+ print(z)
+}
+
+func f20() {
+ // src temporary for channel send
+ if b {
+ ch <- nil // ERROR "live at call to chansend1: autotmp_[0-9]+$"
+ }
+ ch <- nil // ERROR "live at call to chansend1: autotmp_[0-9]+$"
+ ch <- nil // ERROR "live at call to chansend1: autotmp_[0-9]+$"
+}
+
+func f21() {
+ // key temporary for mapaccess using array literal key.
+ var z *byte
+ if b {
+ z = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
+ }
+ z = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
+ z = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
+ print(z)
+}
+
+func f23() {
+ // key temporary for two-result map access using array literal key.
+ var z *byte
+ var ok bool
+ if b {
+ z, ok = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess2: autotmp_[0-9]+$"
+ }
+ z, ok = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess2: autotmp_[0-9]+$"
+ z, ok = m2[[2]string{"x", "y"}] // ERROR "live at call to mapaccess2: autotmp_[0-9]+$"
+ print(z, ok)
+}
+
+func f24() {
+ // key temporary for map access using array literal key.
+ // value temporary too.
+ if b {
+ m2[[2]string{"x", "y"}] = nil // ERROR "live at call to mapassign1: autotmp_[0-9]+ autotmp_[0-9]+$"
+ }
+ m2[[2]string{"x", "y"}] = nil // ERROR "live at call to mapassign1: autotmp_[0-9]+ autotmp_[0-9]+$"
+ m2[[2]string{"x", "y"}] = nil // ERROR "live at call to mapassign1: autotmp_[0-9]+ autotmp_[0-9]+$"
+}
+
+// defer should not cause spurious ambiguously live variables
+
+func f25(b bool) {
+ defer g25()
+ if b {
+ return
+ }
+ var x string
+ _ = &x
+ x = g15() // ERROR "live at call to g15: x"
+ print(x) // ERROR "live at call to printstring: x"
+} // ERROR "live at call to deferreturn: x"
+
+func g25()
+
+// non-escaping ... slices passed to function call should die on return,
+// so that the temporaries do not stack and do not cause ambiguously
+// live variables.
+
+func f26(b bool) {
+ if b {
+ print26(1,2,3) // ERROR "live at call to print26: autotmp_[0-9]+$"
+ }
+ print26(4,5,6) // ERROR "live at call to print26: autotmp_[0-9]+$"
+ print26(7,8,9) // ERROR "live at call to print26: autotmp_[0-9]+$"
+ println()
+}
+
+//go:noescape
+func print26(...interface{})
+
+// non-escaping closures passed to function call should die on return
+
+func f27(b bool) {
+ x := 0
+ if b {
+ call27(func() {x++}) // ERROR "live at call to call27: autotmp_[0-9]+$"
+ }
+ call27(func() {x++}) // ERROR "live at call to call27: autotmp_[0-9]+$"
+ call27(func() {x++}) // ERROR "live at call to call27: autotmp_[0-9]+$"
+ println()
+}
+
+// but defer does escape to later execution in the function
+
+func f27defer(b bool) {
+ x := 0
+ if b {
+ defer call27(func() {x++}) // ERROR "live at call to deferproc: autotmp_[0-9]+$" "live at call to deferreturn: autotmp_[0-9]+$"
+ }
+ defer call27(func() {x++}) // ERROR "live at call to deferproc: autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to deferreturn: autotmp_[0-9]+ autotmp_[0-9]+$" "ambiguously live"
+ println() // ERROR "live at call to printnl: autotmp_[0-9]+ autotmp_[0-9]+$"
+} // ERROR "live at call to deferreturn: autotmp_[0-9]+ autotmp_[0-9]+$"
+
+// and newproc (go) escapes to the heap
+
+func f27go(b bool) {
+ x := 0
+ if b {
+ go call27(func() {x++}) // ERROR "live at call to new: &x" "live at call to newproc: &x$"
+ }
+ go call27(func() {x++}) // ERROR "live at call to new: &x"
+ println()
+}
+
+//go:noescape
+func call27(func())
+
+// concatstring slice should die on return
+
+var s1, s2, s3, s4, s5, s6, s7, s8, s9, s10 string
+
+func f28(b bool) {
+ if b {
+ print(s1+s2+s3+s4+s5+s6+s7+s8+s9+s10) // ERROR "live at call to concatstrings: autotmp_[0-9]+$" "live at call to printstring: autotmp_[0-9]+$"
+ }
+ print(s1+s2+s3+s4+s5+s6+s7+s8+s9+s10) // ERROR "live at call to concatstrings: autotmp_[0-9]+$" "live at call to printstring: autotmp_[0-9]+$"
+ print(s1+s2+s3+s4+s5+s6+s7+s8+s9+s10) // ERROR "live at call to concatstrings: autotmp_[0-9]+$" "live at call to printstring: autotmp_[0-9]+$"
+}
+
+// map iterator should die on end of range loop
+
+func f29(b bool) {
+ if b {
+ for k := range m { // ERROR "live at call to mapiterinit: autotmp_[0-9]+$" "live at call to mapiternext: autotmp_[0-9]+$"
+ print(k) // ERROR "live at call to printstring: autotmp_[0-9]+$"
+ }
+ }
+ for k := range m { // ERROR "live at call to mapiterinit: autotmp_[0-9]+$" "live at call to mapiternext: autotmp_[0-9]+$"
+ print(k) // ERROR "live at call to printstring: autotmp_[0-9]+$"
+ }
+ for k := range m { // ERROR "live at call to mapiterinit: autotmp_[0-9]+$" "live at call to mapiternext: autotmp_[0-9]+$"
+ print(k) // ERROR "live at call to printstring: autotmp_[0-9]+$"
+ }
+}
+
+// copy of array of pointers should die at end of range loop
+
+var ptrarr [10]*int
+
+func f30(b bool) {
+ // two live temps during print(p):
+ // the copy of ptrarr and the internal iterator pointer.
+ if b {
+ for _, p := range ptrarr {
+ print(p) // ERROR "live at call to printpointer: autotmp_[0-9]+ autotmp_[0-9]+$"
+ }
+ }
+ for _, p := range ptrarr {
+ print(p) // ERROR "live at call to printpointer: autotmp_[0-9]+ autotmp_[0-9]+$"
+ }
+ for _, p := range ptrarr {
+ print(p) // ERROR "live at call to printpointer: autotmp_[0-9]+ autotmp_[0-9]+$"
+ }
+}
+
+// conversion to interface should not leave temporary behind
+
+func f31(b1, b2, b3 bool) {
+ if b1 {
+ g31("a") // ERROR "live at call to convT2E: autotmp_[0-9]+$" "live at call to g31: autotmp_[0-9]+$"
+ }
+ if b2 {
+ h31("b") // ERROR "live at call to new: autotmp_[0-9]+$" "live at call to convT2E: autotmp_[0-9]+ autotmp_[0-9]+$" "live at call to h31: autotmp_[0-9]+$"
+ }
+ if b3 {
+ panic("asdf") // ERROR "live at call to convT2E: autotmp_[0-9]+$" "live at call to panic: autotmp_[0-9]+$"
+ }
+ print(b3)
+}
+
+func g31(interface{})
+func h31(...interface{})
+
+// non-escaping partial functions passed to function call should die on return
+
+type T32 int
+
+func (t *T32) Inc() { // ERROR "live at entry"
+ *t++
+}
+
+var t32 T32
+
+func f32(b bool) {
+ if b {
+ call32(t32.Inc) // ERROR "live at call to call32: autotmp_[0-9]+$"
+ }
+ call32(t32.Inc) // ERROR "live at call to call32: autotmp_[0-9]+$"
+ call32(t32.Inc) // ERROR "live at call to call32: autotmp_[0-9]+$"
+}
+
+//go:noescape
+func call32(func())
+
+// temporaries introduced during if conditions and && || expressions
+// should die once the condition has been acted upon.
+
+var m33 map[interface{}]int
+
+func f33() {
+ if m33[nil] == 0 { // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
+ println()
+ return
+ } else {
+ println()
+ }
+ println()
+}
+
+func f34() {
+ if m33[nil] == 0 { // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
+ println()
+ return
+ }
+ println()
+}
+
+func f35() {
+ if m33[nil] == 0 && m33[nil] == 0 { // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
+ println()
+ return
+ }
+ println()
+}
+
+func f36() {
+ if m33[nil] == 0 || m33[nil] == 0 { // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
+ println()
+ return
+ }
+ println()
+}
+
+func f37() {
+ if (m33[nil] == 0 || m33[nil] == 0) && m33[nil] == 0 { // ERROR "live at call to mapaccess1: autotmp_[0-9]+$"
+ println()
+ return
+ }
+ println()
+}
+
+// select temps should disappear in the case bodies
+
+var c38 chan string
+
+func fc38() chan string
+func fi38(int) *string
+func fb38() *bool
+
+func f38(b bool) {
+ // we don't care what temps are printed on the lines with output.
+ // we care that the println lines have no live variables
+ // and therefore no output.
+ if b {
+ select { // ERROR "live at call"
+ case <-fc38(): // ERROR "live at call"
+ println()
+ case fc38() <- *fi38(1): // ERROR "live at call"
+ println()
+ case *fi38(2) = <-fc38(): // ERROR "live at call"
+ println()
+ case *fi38(3), *fb38() = <-fc38(): // ERROR "live at call"
+ println()
+ }
+ println()
+ }
+ println()
+}
+
+// issue 8097: mishandling of x = x during return.
+
+func f39() (x []int) {
+ x = []int{1}
+ println() // ERROR "live at call to printnl: x"
+ return x
+}
+
+func f39a() (x []int) {
+ x = []int{1}
+ println() // ERROR "live at call to printnl: x"
+ return
+}
+
+func f39b() (x [10]*int) {
+ x = [10]*int{new(int)} // ERROR "live at call to new: x"
+ println() // ERROR "live at call to printnl: x"
+ return x
+}
+
+func f39c() (x [10]*int) {
+ x = [10]*int{new(int)} // ERROR "live at call to new: x"
+ println() // ERROR "live at call to printnl: x"
+ return
+}
+
+// issue 8142: lost 'addrtaken' bit on inlined variables.
+// no inlining in this test, so just checking that non-inlined works.
+
+type T40 struct {
+ m map[int]int
+}
+
+func newT40() *T40 {
+ ret := T40{ // ERROR "live at call to makemap: &ret"
+ make(map[int]int),
+ }
+ return &ret
+}
+
+func bad40() {
+ t := newT40()
+ println()
+ _ = t
+}
+
+func good40() {
+ ret := T40{ // ERROR "live at call to makemap: ret"
+ make(map[int]int),
+ }
+ t := &ret
+ println() // ERROR "live at call to printnl: ret"
+ _ = t
+}
diff --git a/test/live1.go b/test/live1.go
new file mode 100644
index 000000000..b05ec1f59
--- /dev/null
+++ b/test/live1.go
@@ -0,0 +1,46 @@
+// compile
+
+// Copyright 2014 The Go 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 code compiles without
+// "internal error: ... recorded as live on entry" errors
+// from the liveness code.
+//
+// This code contains methods or other construct that
+// trigger the generation of wrapper functions with no
+// clear line number (they end up using line 1), and those
+// would have annotations printed if we used -live=1,
+// like the live.go test does.
+// Instead, this test relies on the fact that the liveness
+// analysis turns any non-live parameter on entry into
+// a compile error. Compiling successfully means that bug
+// has been avoided.
+
+package main
+
+// The liveness analysis used to get confused by the tail return
+// instruction in the wrapper methods generated for T1.M and (*T1).M,
+// causing a spurious "live at entry: ~r1" for the return result.
+
+type T struct {
+}
+
+func (t *T) M() *int
+
+type T1 struct {
+ *T
+}
+
+// Liveness analysis used to have the VARDEFs in the wrong place,
+// causing a temporary to appear live on entry.
+
+func f1(pkg, typ, meth string) {
+ panic("value method " + pkg + "." + typ + "." + meth + " called using nil *" + typ + " pointer")
+}
+
+func f2() interface{} {
+ return new(int)
+}
+
diff --git a/test/live2.go b/test/live2.go
new file mode 100644
index 000000000..1e3279402
--- /dev/null
+++ b/test/live2.go
@@ -0,0 +1,39 @@
+// errorcheck -0 -live
+
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// liveness tests with inlining ENABLED
+// see also live.go.
+
+package main
+
+// issue 8142: lost 'addrtaken' bit on inlined variables.
+// no inlining in this test, so just checking that non-inlined works.
+
+type T40 struct {
+ m map[int]int
+}
+
+func newT40() *T40 {
+ ret := T40{ // ERROR "live at call to makemap: &ret"
+ make(map[int]int),
+ }
+ return &ret
+}
+
+func bad40() {
+ t := newT40() // ERROR "live at call to makemap: ret"
+ println() // ERROR "live at call to printnl: ret"
+ _ = t
+}
+
+func good40() {
+ ret := T40{ // ERROR "live at call to makemap: ret"
+ make(map[int]int),
+ }
+ t := &ret
+ println() // ERROR "live at call to printnl: ret"
+ _ = t
+}
diff --git a/test/method4.dir/prog.go b/test/method4.dir/prog.go
index 77d580cff..cb5cf65f2 100644
--- a/test/method4.dir/prog.go
+++ b/test/method4.dir/prog.go
@@ -73,7 +73,14 @@ func main() {
f4 := I2.Sum
eq(f4(t1, a, 17), 27)
eq(f4(t2, a, 18), 28)
-
+
+ // issue 6723
+ f5 := (interface {
+ I2
+ }).Sum
+ eq(f5(t1, a, 19), 29)
+ eq(f5(t2, a, 20), 30)
+
mt1 := method4a.T1(4)
mt2 := &method4a.T2{4}
diff --git a/test/nilptr3.go b/test/nilptr3.go
index 08597a02d..2757daef0 100644
--- a/test/nilptr3.go
+++ b/test/nilptr3.go
@@ -17,7 +17,7 @@ type Struct struct {
type BigStruct struct {
X int
Y float64
- A [1<<20]int
+ A [1 << 20]int
Z string
}
@@ -29,93 +29,94 @@ type Empty1 struct {
}
var (
- intp *int
- arrayp *[10]int
- array0p *[0]int
- bigarrayp *[1<<26]int
- structp *Struct
+ intp *int
+ arrayp *[10]int
+ array0p *[0]int
+ bigarrayp *[1 << 26]int
+ structp *Struct
bigstructp *BigStruct
- emptyp *Empty
- empty1p *Empty1
+ emptyp *Empty
+ empty1p *Empty1
)
func f1() {
_ = *intp // ERROR "generated nil check"
-
+
// This one should be removed but the block copy needs
// to be turned into its own pseudo-op in order to see
// the indirect.
_ = *arrayp // ERROR "generated nil check"
-
- // 0-byte indirect doesn't suffice
+
+ // 0-byte indirect doesn't suffice.
+ // we don't registerize globals, so there are no removed repeated nil checks.
+ _ = *array0p // ERROR "generated nil check"
_ = *array0p // ERROR "generated nil check"
- _ = *array0p // ERROR "removed repeated nil check" 386
- _ = *intp // ERROR "removed repeated nil check"
- _ = *arrayp // ERROR "removed repeated nil check"
+ _ = *intp // ERROR "generated nil check"
+ _ = *arrayp // ERROR "generated nil check"
_ = *structp // ERROR "generated nil check"
- _ = *emptyp // ERROR "generated nil check"
- _ = *arrayp // ERROR "removed repeated nil check"
+ _ = *emptyp // ERROR "generated nil check"
+ _ = *arrayp // ERROR "generated nil check"
}
func f2() {
var (
- intp *int
- arrayp *[10]int
- array0p *[0]int
- bigarrayp *[1<<20]int
- structp *Struct
+ intp *int
+ arrayp *[10]int
+ array0p *[0]int
+ bigarrayp *[1 << 20]int
+ structp *Struct
bigstructp *BigStruct
- emptyp *Empty
- empty1p *Empty1
+ emptyp *Empty
+ empty1p *Empty1
)
- _ = *intp // ERROR "generated nil check"
- _ = *arrayp // ERROR "generated nil check"
- _ = *array0p // ERROR "generated nil check"
- _ = *array0p // ERROR "removed repeated nil check"
- _ = *intp // ERROR "removed repeated nil check"
- _ = *arrayp // ERROR "removed repeated nil check"
- _ = *structp // ERROR "generated nil check"
- _ = *emptyp // ERROR "generated nil check"
- _ = *arrayp // ERROR "removed repeated nil check"
- _ = *bigarrayp // ERROR "generated nil check" ARM removed nil check before indirect!!
+ _ = *intp // ERROR "generated nil check"
+ _ = *arrayp // ERROR "generated nil check"
+ _ = *array0p // ERROR "generated nil check"
+ _ = *array0p // ERROR "removed repeated nil check"
+ _ = *intp // ERROR "removed repeated nil check"
+ _ = *arrayp // ERROR "removed repeated nil check"
+ _ = *structp // ERROR "generated nil check"
+ _ = *emptyp // ERROR "generated nil check"
+ _ = *arrayp // ERROR "removed repeated nil check"
+ _ = *bigarrayp // ERROR "generated nil check" ARM removed nil check before indirect!!
_ = *bigstructp // ERROR "generated nil check"
- _ = *empty1p // ERROR "generated nil check"
+ _ = *empty1p // ERROR "generated nil check"
}
func fx10k() *[10000]int
-var b bool
+var b bool
func f3(x *[10000]int) {
// Using a huge type and huge offsets so the compiler
// does not expect the memory hardware to fault.
_ = x[9999] // ERROR "generated nil check"
-
+
for {
if x[9999] != 0 { // ERROR "generated nil check"
break
}
}
-
- x = fx10k()
+
+ x = fx10k()
_ = x[9999] // ERROR "generated nil check"
if b {
_ = x[9999] // ERROR "removed repeated nil check"
} else {
_ = x[9999] // ERROR "removed repeated nil check"
- }
+ }
_ = x[9999] // ERROR "generated nil check"
- x = fx10k()
+ x = fx10k()
if b {
_ = x[9999] // ERROR "generated nil check"
} else {
_ = x[9999] // ERROR "generated nil check"
- }
+ }
_ = x[9999] // ERROR "generated nil check"
-
+
fx10k()
// This one is a bit redundant, if we figured out that
// x wasn't going to change across the function call.
@@ -145,7 +146,7 @@ func f3b() {
_ = &x[9] // ERROR "removed repeated nil check"
}
-func fx10() *[10]int
+func fx10() *[10]int
func f4(x *[10]int) {
// Most of these have no checks because a real memory reference follows,
@@ -153,14 +154,14 @@ func f4(x *[10]int) {
// in the first unmapped page of memory.
_ = x[9] // ERROR "removed nil check before indirect"
-
+
for {
if x[9] != 0 { // ERROR "removed nil check before indirect"
break
}
}
-
- x = fx10()
+
+ x = fx10()
_ = x[9] // ERROR "removed nil check before indirect"
if b {
_ = x[9] // ERROR "removed nil check before indirect"
@@ -169,17 +170,17 @@ func f4(x *[10]int) {
}
_ = x[9] // ERROR "removed nil check before indirect"
- x = fx10()
+ x = fx10()
if b {
_ = x[9] // ERROR "removed nil check before indirect"
} else {
_ = &x[9] // ERROR "generated nil check"
- }
+ }
_ = x[9] // ERROR "removed nil check before indirect"
-
+
fx10()
_ = x[9] // ERROR "removed nil check before indirect"
-
+
x = fx10()
y := fx10()
_ = &x[9] // ERROR "generated nil check"
@@ -188,4 +189,3 @@ func f4(x *[10]int) {
x = y
_ = &x[9] // ERROR "removed repeated nil check"
}
-
diff --git a/test/nilptr4.go b/test/nilptr4.go
new file mode 100644
index 000000000..3dd7d4e02
--- /dev/null
+++ b/test/nilptr4.go
@@ -0,0 +1,24 @@
+// build
+
+// Copyright 2014 The Go 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 the compiler does not crash during compilation.
+
+package main
+
+import "unsafe"
+
+// Issue 7413
+func f1() {
+ type t struct {
+ i int
+ }
+
+ var v *t
+ _ = int(uintptr(unsafe.Pointer(&v.i)))
+ _ = int32(uintptr(unsafe.Pointer(&v.i)))
+}
+
+func main() {}
diff --git a/test/nosplit.go b/test/nosplit.go
new file mode 100644
index 000000000..35aa51017
--- /dev/null
+++ b/test/nosplit.go
@@ -0,0 +1,314 @@
+// run
+
+// +build !nacl
+
+// Copyright 2014 The Go 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 (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "regexp"
+ "runtime"
+ "strconv"
+ "strings"
+)
+
+var tests = `
+# These are test cases for the linker analysis that detects chains of
+# nosplit functions that would cause a stack overflow.
+#
+# Lines beginning with # are comments.
+#
+# Each test case describes a sequence of functions, one per line.
+# Each function definition is the function name, then the frame size,
+# then optionally the keyword 'nosplit', then the body of the function.
+# The body is assembly code, with some shorthands.
+# The shorthand 'call x' stands for CALL x(SB).
+# The shorthand 'callind' stands for 'CALL R0', where R0 is a register.
+# Each test case must define a function named main, and it must be first.
+# That is, a line beginning "main " indicates the start of a new test case.
+# Within a stanza, ; can be used instead of \n to separate lines.
+#
+# After the function definition, the test case ends with an optional
+# REJECT line, specifying the architectures on which the case should
+# be rejected. "REJECT" without any architectures means reject on all architectures.
+# The linker should accept the test case on systems not explicitly rejected.
+#
+# 64-bit systems do not attempt to execute test cases with frame sizes
+# that are only 32-bit aligned.
+
+# Ordinary function should work
+main 0
+
+# Large frame marked nosplit is always wrong.
+main 10000 nosplit
+REJECT
+
+# Calling a large frame is okay.
+main 0 call big
+big 10000
+
+# But not if the frame is nosplit.
+main 0 call big
+big 10000 nosplit
+REJECT
+
+# Recursion is okay.
+main 0 call main
+
+# Recursive nosplit runs out of space.
+main 0 nosplit call main
+REJECT
+
+# Chains of ordinary functions okay.
+main 0 call f1
+f1 80 call f2
+f2 80
+
+# Chains of nosplit must fit in the stack limit, 128 bytes.
+main 0 call f1
+f1 80 nosplit call f2
+f2 80 nosplit
+REJECT
+
+# Larger chains.
+main 0 call f1
+f1 16 call f2
+f2 16 call f3
+f3 16 call f4
+f4 16 call f5
+f5 16 call f6
+f6 16 call f7
+f7 16 call f8
+f8 16 call end
+end 1000
+
+main 0 call f1
+f1 16 nosplit call f2
+f2 16 nosplit call f3
+f3 16 nosplit call f4
+f4 16 nosplit call f5
+f5 16 nosplit call f6
+f6 16 nosplit call f7
+f7 16 nosplit call f8
+f8 16 nosplit call end
+end 1000
+REJECT
+
+# Test cases near the 128-byte limit.
+
+# Ordinary stack split frame is always okay.
+main 112
+main 116
+main 120
+main 124
+main 128
+main 132
+main 136
+
+# A nosplit leaf can use the whole 128-CallSize bytes available on entry.
+main 112 nosplit
+main 116 nosplit
+main 120 nosplit
+main 124 nosplit
+main 128 nosplit; REJECT
+main 132 nosplit; REJECT
+main 136 nosplit; REJECT
+
+# Calling a nosplit function from a nosplit function requires
+# having room for the saved caller PC and the called frame.
+# Because ARM doesn't save LR in the leaf, it gets an extra 4 bytes.
+main 112 nosplit call f; f 0 nosplit
+main 116 nosplit call f; f 0 nosplit; REJECT amd64
+main 120 nosplit call f; f 0 nosplit; REJECT amd64
+main 124 nosplit call f; f 0 nosplit; REJECT amd64 386
+main 128 nosplit call f; f 0 nosplit; REJECT
+main 132 nosplit call f; f 0 nosplit; REJECT
+main 136 nosplit call f; f 0 nosplit; REJECT
+
+# Calling a splitting function from a nosplit function requires
+# having room for the saved caller PC of the call but also the
+# saved caller PC for the call to morestack. Again the ARM works
+# in less space.
+main 104 nosplit call f; f 0 call f
+main 108 nosplit call f; f 0 call f
+main 112 nosplit call f; f 0 call f; REJECT amd64
+main 116 nosplit call f; f 0 call f; REJECT amd64
+main 120 nosplit call f; f 0 call f; REJECT amd64 386
+main 124 nosplit call f; f 0 call f; REJECT amd64 386
+main 128 nosplit call f; f 0 call f; REJECT
+main 132 nosplit call f; f 0 call f; REJECT
+main 136 nosplit call f; f 0 call f; REJECT
+
+# Indirect calls are assumed to be splitting functions.
+main 104 nosplit callind
+main 108 nosplit callind
+main 112 nosplit callind; REJECT amd64
+main 116 nosplit callind; REJECT amd64
+main 120 nosplit callind; REJECT amd64 386
+main 124 nosplit callind; REJECT amd64 386
+main 128 nosplit callind; REJECT
+main 132 nosplit callind; REJECT
+main 136 nosplit callind; REJECT
+
+# Issue 7623
+main 0 call f; f 112
+main 0 call f; f 116
+main 0 call f; f 120
+main 0 call f; f 124
+main 0 call f; f 128
+main 0 call f; f 132
+main 0 call f; f 136
+`
+
+var (
+ commentRE = regexp.MustCompile(`(?m)^#.*`)
+ rejectRE = regexp.MustCompile(`(?s)\A(.+?)((\n|; *)REJECT(.*))?\z`)
+ lineRE = regexp.MustCompile(`(\w+) (\d+)( nosplit)?(.*)`)
+ callRE = regexp.MustCompile(`\bcall (\w+)\b`)
+ callindRE = regexp.MustCompile(`\bcallind\b`)
+)
+
+func main() {
+ goarch := os.Getenv("GOARCH")
+ if goarch == "" {
+ goarch = runtime.GOARCH
+ }
+
+ dir, err := ioutil.TempDir("", "go-test-nosplit")
+ if err != nil {
+ bug()
+ fmt.Printf("creating temp dir: %v\n", err)
+ return
+ }
+ defer os.RemoveAll(dir)
+ ioutil.WriteFile(filepath.Join(dir, "main.go"), []byte("package main\nfunc main()\n"), 0666)
+
+ tests = strings.Replace(tests, "\t", " ", -1)
+ tests = commentRE.ReplaceAllString(tests, "")
+
+ nok := 0
+ nfail := 0
+TestCases:
+ for len(tests) > 0 {
+ var stanza string
+ i := strings.Index(tests, "\nmain ")
+ if i < 0 {
+ stanza, tests = tests, ""
+ } else {
+ stanza, tests = tests[:i], tests[i+1:]
+ }
+
+ m := rejectRE.FindStringSubmatch(stanza)
+ if m == nil {
+ bug()
+ fmt.Printf("invalid stanza:\n\t%s\n", indent(stanza))
+ continue
+ }
+ lines := strings.TrimSpace(m[1])
+ reject := false
+ if m[2] != "" {
+ if strings.TrimSpace(m[4]) == "" {
+ reject = true
+ } else {
+ for _, rej := range strings.Fields(m[4]) {
+ if rej == goarch {
+ reject = true
+ }
+ }
+ }
+ }
+ if lines == "" && !reject {
+ continue
+ }
+
+ var buf bytes.Buffer
+ if goarch == "arm" {
+ fmt.Fprintf(&buf, "#define CALL BL\n#define REGISTER (R0)\n")
+ } else {
+ fmt.Fprintf(&buf, "#define REGISTER AX\n")
+ }
+
+ for _, line := range strings.Split(lines, "\n") {
+ line = strings.TrimSpace(line)
+ if line == "" {
+ continue
+ }
+ for _, subline := range strings.Split(line, ";") {
+ subline = strings.TrimSpace(subline)
+ if subline == "" {
+ continue
+ }
+ m := lineRE.FindStringSubmatch(subline)
+ if m == nil {
+ bug()
+ fmt.Printf("invalid function line: %s\n", subline)
+ continue TestCases
+ }
+ name := m[1]
+ size, _ := strconv.Atoi(m[2])
+ if goarch == "amd64" && size%8 == 4 {
+ continue TestCases
+ }
+ nosplit := m[3]
+ body := m[4]
+
+ if nosplit != "" {
+ nosplit = ",7"
+ } else {
+ nosplit = ",0"
+ }
+ body = callRE.ReplaceAllString(body, "CALL ·$1(SB);")
+ body = callindRE.ReplaceAllString(body, "CALL REGISTER;")
+
+ fmt.Fprintf(&buf, "TEXT ·%s(SB)%s,$%d-0\n\t%s\n\tRET\n\n", name, nosplit, size, body)
+ }
+ }
+
+ ioutil.WriteFile(filepath.Join(dir, "asm.s"), buf.Bytes(), 0666)
+
+ cmd := exec.Command("go", "build")
+ cmd.Dir = dir
+ output, err := cmd.CombinedOutput()
+ if err == nil {
+ nok++
+ if reject {
+ bug()
+ fmt.Printf("accepted incorrectly:\n\t%s\n", indent(strings.TrimSpace(stanza)))
+ }
+ } else {
+ nfail++
+ if !reject {
+ bug()
+ fmt.Printf("rejected incorrectly:\n\t%s\n", indent(strings.TrimSpace(stanza)))
+ fmt.Printf("\n\tlinker output:\n\t%s\n", indent(string(output)))
+ }
+ }
+ }
+
+ if !bugged && (nok == 0 || nfail == 0) {
+ bug()
+ fmt.Printf("not enough test cases run\n")
+ }
+}
+
+func indent(s string) string {
+ return strings.Replace(s, "\n", "\n\t", -1)
+}
+
+var bugged = false
+
+func bug() {
+ if !bugged {
+ bugged = true
+ fmt.Printf("BUG\n")
+ }
+}
diff --git a/test/reorder2.go b/test/reorder2.go
index d91f1d895..e56be2bc8 100644
--- a/test/reorder2.go
+++ b/test/reorder2.go
@@ -167,6 +167,175 @@ func main() {
err++
}
log = ""
+
+ x := 0
+ switch x {
+ case 0:
+ if a("1")("2")("3"); log != "a(1)a(2)a(3)" {
+ println("in switch, expecting a(1)a(2)a(3) , got ", log)
+ err++
+ }
+ log = ""
+
+ if t.a("1").a(t.b("2")); log != "a(1)b(2)a(2)" {
+ println("in switch, expecting a(1)b(2)a(2), got ", log)
+ err++
+ }
+ log = ""
+ if a("3")(b("4"))(b("5")); log != "a(3)b(4)a(4)b(5)a(5)" {
+ println("in switch, expecting a(3)b(4)a(4)b(5)a(5), got ", log)
+ err++
+ }
+ log = ""
+ var i I = T1(0)
+ if i.a("6").a(i.b("7")).a(i.b("8")).a(i.b("9")); log != "a(6)b(7)a(7)b(8)a(8)b(9)a(9)" {
+ println("in switch, expecting a(6)ba(7)ba(8)ba(9), got", log)
+ err++
+ }
+ log = ""
+ }
+
+ c := make(chan int, 1)
+ c <- 1
+ select {
+ case c <- 0:
+ case c <- 1:
+ case <-c:
+ if a("1")("2")("3"); log != "a(1)a(2)a(3)" {
+ println("in select1, expecting a(1)a(2)a(3) , got ", log)
+ err++
+ }
+ log = ""
+
+ if t.a("1").a(t.b("2")); log != "a(1)b(2)a(2)" {
+ println("in select1, expecting a(1)b(2)a(2), got ", log)
+ err++
+ }
+ log = ""
+ if a("3")(b("4"))(b("5")); log != "a(3)b(4)a(4)b(5)a(5)" {
+ println("in select1, expecting a(3)b(4)a(4)b(5)a(5), got ", log)
+ err++
+ }
+ log = ""
+ var i I = T1(0)
+ if i.a("6").a(i.b("7")).a(i.b("8")).a(i.b("9")); log != "a(6)b(7)a(7)b(8)a(8)b(9)a(9)" {
+ println("in select1, expecting a(6)ba(7)ba(8)ba(9), got", log)
+ err++
+ }
+ log = ""
+ }
+
+ c <- 1
+ select {
+ case <-c:
+ if a("1")("2")("3"); log != "a(1)a(2)a(3)" {
+ println("in select2, expecting a(1)a(2)a(3) , got ", log)
+ err++
+ }
+ log = ""
+
+ if t.a("1").a(t.b("2")); log != "a(1)b(2)a(2)" {
+ println("in select2, expecting a(1)b(2)a(2), got ", log)
+ err++
+ }
+ log = ""
+ if a("3")(b("4"))(b("5")); log != "a(3)b(4)a(4)b(5)a(5)" {
+ println("in select2, expecting a(3)b(4)a(4)b(5)a(5), got ", log)
+ err++
+ }
+ log = ""
+ var i I = T1(0)
+ if i.a("6").a(i.b("7")).a(i.b("8")).a(i.b("9")); log != "a(6)b(7)a(7)b(8)a(8)b(9)a(9)" {
+ println("in select2, expecting a(6)ba(7)ba(8)ba(9), got", log)
+ err++
+ }
+ log = ""
+ }
+
+ c <- 1
+ select {
+ default:
+ case c<-1:
+ case <-c:
+ if a("1")("2")("3"); log != "a(1)a(2)a(3)" {
+ println("in select3, expecting a(1)a(2)a(3) , got ", log)
+ err++
+ }
+ log = ""
+
+ if t.a("1").a(t.b("2")); log != "a(1)b(2)a(2)" {
+ println("in select3, expecting a(1)b(2)a(2), got ", log)
+ err++
+ }
+ log = ""
+ if a("3")(b("4"))(b("5")); log != "a(3)b(4)a(4)b(5)a(5)" {
+ println("in select3, expecting a(3)b(4)a(4)b(5)a(5), got ", log)
+ err++
+ }
+ log = ""
+ var i I = T1(0)
+ if i.a("6").a(i.b("7")).a(i.b("8")).a(i.b("9")); log != "a(6)b(7)a(7)b(8)a(8)b(9)a(9)" {
+ println("in select3, expecting a(6)ba(7)ba(8)ba(9), got", log)
+ err++
+ }
+ log = ""
+ }
+
+ c <- 1
+ select {
+ default:
+ case <-c:
+ if a("1")("2")("3"); log != "a(1)a(2)a(3)" {
+ println("in select4, expecting a(1)a(2)a(3) , got ", log)
+ err++
+ }
+ log = ""
+
+ if t.a("1").a(t.b("2")); log != "a(1)b(2)a(2)" {
+ println("in select4, expecting a(1)b(2)a(2), got ", log)
+ err++
+ }
+ log = ""
+ if a("3")(b("4"))(b("5")); log != "a(3)b(4)a(4)b(5)a(5)" {
+ println("in select4, expecting a(3)b(4)a(4)b(5)a(5), got ", log)
+ err++
+ }
+ log = ""
+ var i I = T1(0)
+ if i.a("6").a(i.b("7")).a(i.b("8")).a(i.b("9")); log != "a(6)b(7)a(7)b(8)a(8)b(9)a(9)" {
+ println("in select4, expecting a(6)ba(7)ba(8)ba(9), got", log)
+ err++
+ }
+ log = ""
+ }
+
+ select {
+ case <-c:
+ case <-c:
+ default:
+ if a("1")("2")("3"); log != "a(1)a(2)a(3)" {
+ println("in select5, expecting a(1)a(2)a(3) , got ", log)
+ err++
+ }
+ log = ""
+
+ if t.a("1").a(t.b("2")); log != "a(1)b(2)a(2)" {
+ println("in select5, expecting a(1)b(2)a(2), got ", log)
+ err++
+ }
+ log = ""
+ if a("3")(b("4"))(b("5")); log != "a(3)b(4)a(4)b(5)a(5)" {
+ println("in select5, expecting a(3)b(4)a(4)b(5)a(5), got ", log)
+ err++
+ }
+ log = ""
+ var i I = T1(0)
+ if i.a("6").a(i.b("7")).a(i.b("8")).a(i.b("9")); log != "a(6)b(7)a(7)b(8)a(8)b(9)a(9)" {
+ println("in select5, expecting a(6)ba(7)ba(8)ba(9), got", log)
+ err++
+ }
+ log = ""
+ }
if err > 0 {
panic("fail")
diff --git a/test/run b/test/run
index d206312a2..729fc1eaa 100755
--- a/test/run
+++ b/test/run
@@ -33,7 +33,7 @@ unset GOROOT_FINAL # breaks ./ imports
failed=0
-PATH=${GOBIN:-$GOROOT/bin}:`pwd`:/bin:/usr/bin:/usr/local/bin
+PATH=${GOBIN:-$GOROOT/bin}:`pwd`:/bin:/usr/bin:/usr/local/bin:/usr/pkg/bin
# TODO: We add the tool directory to the PATH to avoid thinking about a better way.
PATH="$GOTOOLDIR:$PATH"
diff --git a/test/run.go b/test/run.go
index f1f1ec034..a8d4baa3a 100644
--- a/test/run.go
+++ b/test/run.go
@@ -27,6 +27,7 @@ import (
"sort"
"strconv"
"strings"
+ "time"
"unicode"
)
@@ -44,6 +45,8 @@ var (
// letter is the build.ArchChar
letter string
+
+ goos, goarch string
// dirs are the directories to look for *.go files in.
// TODO(bradfitz): just use all directories?
@@ -68,8 +71,12 @@ const maxTests = 5000
func main() {
flag.Parse()
- // Disable parallelism if printing
- if *verbose {
+ goos = os.Getenv("GOOS")
+ goarch = os.Getenv("GOARCH")
+ findExecCmd()
+
+ // Disable parallelism if printing or if using a simulator.
+ if *verbose || len(findExecCmd()) > 0 {
*numParallel = 1
}
@@ -114,28 +121,39 @@ func main() {
failed := false
resCount := map[string]int{}
for _, test := range tests {
- <-test.donec
- _, isSkip := test.err.(skipError)
- errStr := "pass"
+ <-test.donec
+ status := "ok "
+ errStr := ""
+ if _, isSkip := test.err.(skipError); isSkip {
+ status = "skip"
+ test.err = nil
+ if !skipOkay[path.Join(test.dir, test.gofile)] {
+ errStr = "unexpected skip for " + path.Join(test.dir, test.gofile) + ": " + errStr
+ status = "FAIL"
+ }
+ }
if test.err != nil {
+ status = "FAIL"
errStr = test.err.Error()
- if !isSkip {
- failed = true
- }
}
- if isSkip && !skipOkay[path.Join(test.dir, test.gofile)] {
- errStr = "unexpected skip for " + path.Join(test.dir, test.gofile) + ": " + errStr
- isSkip = false
+ if status == "FAIL" {
failed = true
}
- resCount[errStr]++
- if isSkip && !*verbose && !*showSkips {
+ resCount[status]++
+ if status == "skip" && !*verbose && !*showSkips {
continue
}
- if !*verbose && test.err == nil {
+ dt := fmt.Sprintf("%.3fs", test.dt.Seconds())
+ if status == "FAIL" {
+ fmt.Printf("# go run run.go -- %s\n%s\nFAIL\t%s\t%s\n",
+ path.Join(test.dir, test.gofile),
+ errStr, test.goFileName(), dt)
continue
}
- fmt.Printf("# go run run.go -- %s\n%-20s %-20s: %s\n", path.Join(test.dir, test.gofile), test.action, test.goFileName(), errStr)
+ if !*verbose {
+ continue
+ }
+ fmt.Printf("%s\t%s\t%s\n", status, test.goFileName(), dt)
}
if *summary {
@@ -188,7 +206,7 @@ func compileInDir(runcmd runCmd, dir string, names ...string) (out []byte, err e
func linkFile(runcmd runCmd, goname string) (err error) {
pfile := strings.Replace(goname, ".go", "."+letter, -1)
- _, err = runcmd("go", "tool", ld, "-o", "a.exe", "-L", ".", pfile)
+ _, err = runcmd("go", "tool", ld, "-w", "-o", "a.exe", "-L", ".", pfile)
return
}
@@ -207,7 +225,8 @@ func check(err error) {
type test struct {
dir, gofile string
donec chan bool // closed when done
-
+ dt time.Duration
+
src string
action string // "compile", "build", etc.
@@ -379,7 +398,11 @@ func init() { checkShouldTest() }
// run runs a test.
func (t *test) run() {
- defer close(t.donec)
+ start := time.Now()
+ defer func() {
+ t.dt = time.Since(start)
+ close(t.donec)
+ }()
srcBytes, err := ioutil.ReadFile(t.goFileName())
if err != nil {
@@ -396,7 +419,7 @@ func (t *test) run() {
t.err = errors.New("double newline not found")
return
}
- if ok, why := shouldTest(t.src, runtime.GOOS, runtime.GOARCH); !ok {
+ if ok, why := shouldTest(t.src, goos, goarch); !ok {
t.action = "skip"
if *showSkips {
fmt.Printf("%-20s %-20s: %s\n", t.action, t.goFileName(), why)
@@ -456,8 +479,12 @@ func (t *test) run() {
check(err)
// A few tests (of things like the environment) require these to be set.
- os.Setenv("GOOS", runtime.GOOS)
- os.Setenv("GOARCH", runtime.GOARCH)
+ if os.Getenv("GOOS") == "" {
+ os.Setenv("GOOS", runtime.GOOS)
+ }
+ if os.Getenv("GOARCH") == "" {
+ os.Setenv("GOARCH", runtime.GOARCH)
+ }
useTmp := true
runcmd := func(args ...string) ([]byte, error) {
@@ -572,7 +599,11 @@ func (t *test) run() {
t.err = err
return
}
- out, err := runcmd(append([]string{filepath.Join(t.tempDir, "a.exe")}, args...)...)
+ var cmd []string
+ cmd = append(cmd, findExecCmd()...)
+ cmd = append(cmd, filepath.Join(t.tempDir, "a.exe"))
+ cmd = append(cmd, args...)
+ out, err := runcmd(cmd...)
if err != nil {
t.err = err
return
@@ -654,6 +685,23 @@ func (t *test) run() {
}
}
+var execCmd []string
+
+func findExecCmd() []string {
+ if execCmd != nil {
+ return execCmd
+ }
+ execCmd = []string{} // avoid work the second time
+ if goos == runtime.GOOS && goarch == runtime.GOARCH {
+ return execCmd
+ }
+ path, err := exec.LookPath(fmt.Sprintf("go_%s_%s_exec", goos, goarch))
+ if err == nil {
+ execCmd = []string{path}
+ }
+ return execCmd
+}
+
func (t *test) String() string {
return filepath.Join(t.dir, t.gofile)
}
@@ -712,7 +760,7 @@ func (t *test) errorCheck(outStr string, fullshort ...string) (err error) {
for _, we := range want {
var errmsgs []string
- errmsgs, out = partitionStrings(we.filterRe, out)
+ errmsgs, out = partitionStrings(we.prefix, out)
if len(errmsgs) == 0 {
errs = append(errs, fmt.Errorf("%s:%d: missing error %q", we.file, we.lineNum, we.reStr))
continue
@@ -754,9 +802,29 @@ func (t *test) errorCheck(outStr string, fullshort ...string) (err error) {
}
-func partitionStrings(rx *regexp.Regexp, strs []string) (matched, unmatched []string) {
+// matchPrefix reports whether s is of the form ^(.*/)?prefix(:|[),
+// That is, it needs the file name prefix followed by a : or a [,
+// and possibly preceded by a directory name.
+func matchPrefix(s, prefix string) bool {
+ i := strings.Index(s, ":")
+ if i < 0 {
+ return false
+ }
+ j := strings.LastIndex(s[:i], "/")
+ s = s[j+1:]
+ if len(s) <= len(prefix) || s[:len(prefix)] != prefix {
+ return false
+ }
+ switch s[len(prefix)] {
+ case '[', ':':
+ return true
+ }
+ return false
+}
+
+func partitionStrings(prefix string, strs []string) (matched, unmatched []string) {
for _, s := range strs {
- if rx.MatchString(s) {
+ if matchPrefix(s, prefix) {
matched = append(matched, s)
} else {
unmatched = append(unmatched, s)
@@ -770,7 +838,7 @@ type wantedError struct {
re *regexp.Regexp
lineNum int
file string
- filterRe *regexp.Regexp // /^file:linenum\b/m
+ prefix string
}
var (
@@ -780,6 +848,8 @@ var (
)
func (t *test) wantedErrors(file, short string) (errs []wantedError) {
+ cache := make(map[string]*regexp.Regexp)
+
src, _ := ioutil.ReadFile(file)
for i, line := range strings.Split(string(src), "\n") {
lineNum := i + 1
@@ -808,15 +878,20 @@ func (t *test) wantedErrors(file, short string) (errs []wantedError) {
}
return fmt.Sprintf("%s:%d", short, n)
})
- re, err := regexp.Compile(rx)
- if err != nil {
- log.Fatalf("%s:%d: invalid regexp in ERROR line: %v", t.goFileName(), lineNum, err)
+ re := cache[rx]
+ if re == nil {
+ var err error
+ re, err = regexp.Compile(rx)
+ if err != nil {
+ log.Fatalf("%s:%d: invalid regexp in ERROR line: %v", t.goFileName(), lineNum, err)
+ }
+ cache[rx] = re
}
- filterPattern := fmt.Sprintf(`^(\w+/)?%s:%d[:[]`, regexp.QuoteMeta(short), lineNum)
+ prefix := fmt.Sprintf("%s:%d", short, lineNum)
errs = append(errs, wantedError{
reStr: rx,
re: re,
- filterRe: regexp.MustCompile(filterPattern),
+ prefix: prefix,
lineNum: lineNum,
file: short,
})
@@ -869,7 +944,7 @@ func checkShouldTest() {
// Build tags separated by a space are OR-ed together.
assertNot(shouldTest("// +build arm 386", "linux", "amd64"))
- // Build tags seperated by a comma are AND-ed together.
+ // Build tags separated by a comma are AND-ed together.
assertNot(shouldTest("// +build !windows,!plan9", "windows", "amd64"))
assertNot(shouldTest("// +build !windows,!plan9", "plan9", "386"))
diff --git a/test/sigchld.go b/test/sigchld.go
index a60d28dea..38437e552 100644
--- a/test/sigchld.go
+++ b/test/sigchld.go
@@ -1,4 +1,4 @@
-// +build !windows
+// +build !plan9,!windows
// cmpout
// Copyright 2009 The Go Authors. All rights reserved.
diff --git a/test/slice3err.go b/test/slice3err.go
index 906b00703..83fb39be4 100644
--- a/test/slice3err.go
+++ b/test/slice3err.go
@@ -54,58 +54,58 @@ func f() {
// check invalid indices
_ = array[1:2]
- _ = array[2:1] // ERROR "invalid slice index"
+ _ = array[2:1] // ERROR "invalid slice index|inverted slice"
_ = array[2:2]
_ = array[i:1]
_ = array[1:j]
_ = array[1:2:3]
- _ = array[1:3:2] // ERROR "invalid slice index"
- _ = array[2:1:3] // ERROR "invalid slice index"
- _ = array[2:3:1] // ERROR "invalid slice index"
- _ = array[3:1:2] // ERROR "invalid slice index"
- _ = array[3:2:1] // ERROR "invalid slice index"
+ _ = array[1:3:2] // ERROR "invalid slice index|inverted slice"
+ _ = array[2:1:3] // ERROR "invalid slice index|inverted slice"
+ _ = array[2:3:1] // ERROR "invalid slice index|inverted slice"
+ _ = array[3:1:2] // ERROR "invalid slice index|inverted slice"
+ _ = array[3:2:1] // ERROR "invalid slice index|inverted slice"
_ = array[i:1:2]
- _ = array[i:2:1] // ERROR "invalid slice index"
+ _ = array[i:2:1] // ERROR "invalid slice index|inverted slice"
_ = array[1:j:2]
_ = array[2:j:1] // ERROR "invalid slice index"
_ = array[1:2:k]
- _ = array[2:1:k] // ERROR "invalid slice index"
+ _ = array[2:1:k] // ERROR "invalid slice index|inverted slice"
_ = slice[1:2]
- _ = slice[2:1] // ERROR "invalid slice index"
+ _ = slice[2:1] // ERROR "invalid slice index|inverted slice"
_ = slice[2:2]
_ = slice[i:1]
_ = slice[1:j]
_ = slice[1:2:3]
- _ = slice[1:3:2] // ERROR "invalid slice index"
- _ = slice[2:1:3] // ERROR "invalid slice index"
- _ = slice[2:3:1] // ERROR "invalid slice index"
- _ = slice[3:1:2] // ERROR "invalid slice index"
- _ = slice[3:2:1] // ERROR "invalid slice index"
+ _ = slice[1:3:2] // ERROR "invalid slice index|inverted slice"
+ _ = slice[2:1:3] // ERROR "invalid slice index|inverted slice"
+ _ = slice[2:3:1] // ERROR "invalid slice index|inverted slice"
+ _ = slice[3:1:2] // ERROR "invalid slice index|inverted slice"
+ _ = slice[3:2:1] // ERROR "invalid slice index|inverted slice"
_ = slice[i:1:2]
- _ = slice[i:2:1] // ERROR "invalid slice index"
+ _ = slice[i:2:1] // ERROR "invalid slice index|inverted slice"
_ = slice[1:j:2]
_ = slice[2:j:1] // ERROR "invalid slice index"
_ = slice[1:2:k]
- _ = slice[2:1:k] // ERROR "invalid slice index"
+ _ = slice[2:1:k] // ERROR "invalid slice index|inverted slice"
_ = str[1:2]
- _ = str[2:1] // ERROR "invalid slice index"
+ _ = str[2:1] // ERROR "invalid slice index|inverted slice"
_ = str[2:2]
_ = str[i:1]
_ = str[1:j]
// check out of bounds indices on array
- _ = array[11:11] // ERROR "out of bounds for 10-element array"
- _ = array[11:12] // ERROR "out of bounds for 10-element array"
- _ = array[11:] // ERROR "out of bounds for 10-element array"
- _ = array[:11] // ERROR "out of bounds for 10-element array"
- _ = array[1:11] // ERROR "out of bounds for 10-element array"
- _ = array[1:11:12] // ERROR "out of bounds for 10-element array"
- _ = array[1:2:11] // ERROR "out of bounds for 10-element array"
- _ = array[1:11:3] // ERROR "out of bounds for 10-element array"
- _ = array[11:2:3] // ERROR "out of bounds for 10-element array"
- _ = array[11:12:13] // ERROR "out of bounds for 10-element array"
+ _ = array[11:11] // ERROR "out of bounds"
+ _ = array[11:12] // ERROR "out of bounds"
+ _ = array[11:] // ERROR "out of bounds"
+ _ = array[:11] // ERROR "out of bounds"
+ _ = array[1:11] // ERROR "out of bounds"
+ _ = array[1:11:12] // ERROR "out of bounds"
+ _ = array[1:2:11] // ERROR "out of bounds"
+ _ = array[1:11:3] // ERROR "out of bounds|invalid slice index"
+ _ = array[11:2:3] // ERROR "out of bounds|inverted slice|invalid slice index"
+ _ = array[11:12:13] // ERROR "out of bounds"
// slice bounds not checked
_ = slice[11:11]
@@ -116,6 +116,6 @@ func f() {
_ = slice[1:11:12]
_ = slice[1:2:11]
_ = slice[1:11:3] // ERROR "invalid slice index"
- _ = slice[11:2:3] // ERROR "invalid slice index"
+ _ = slice[11:2:3] // ERROR "invalid slice index|inverted slice"
_ = slice[11:12:13]
}
diff --git a/test/string_lit.go b/test/string_lit.go
index fea6f553d..4751b82cc 100644
--- a/test/string_lit.go
+++ b/test/string_lit.go
@@ -125,6 +125,11 @@ func main() {
s = string(-1)
assert(s, "\xef\xbf\xbd", "negative rune")
+ // the large rune tests yet again, with a slice.
+ rs := []rune{0x10ffff, 0x10ffff + 1, 0xD800, 0xDFFF, -1}
+ s = string(rs)
+ assert(s, "\xf4\x8f\xbf\xbf\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd", "large rune slice")
+
assert(string(gr1), gx1, "global ->[]rune")
assert(string(gr2), gx2fix, "global invalid ->[]rune")
assert(string(gb1), gx1, "->[]byte")
diff --git a/test/syntax/semi1.go b/test/syntax/semi1.go
index cc30f2654..6e0428121 100644
--- a/test/syntax/semi1.go
+++ b/test/syntax/semi1.go
@@ -7,7 +7,7 @@
package main
func main() {
- if x; y // ERROR "missing { after if clause|undefined"
+ if x; y // ERROR "missing .*{.* after if clause|undefined"
{
z // GCCGO_ERROR "undefined"
diff --git a/test/syntax/semi2.go b/test/syntax/semi2.go
index 61b8bf6d4..23d7bd0ee 100644
--- a/test/syntax/semi2.go
+++ b/test/syntax/semi2.go
@@ -7,7 +7,7 @@
package main
func main() {
- switch x; y // ERROR "missing { after switch clause|undefined"
+ switch x; y // ERROR "missing .*{.* after switch clause|undefined"
{
z
diff --git a/test/syntax/semi3.go b/test/syntax/semi3.go
index bb87520c5..ca070d8a5 100644
--- a/test/syntax/semi3.go
+++ b/test/syntax/semi3.go
@@ -7,7 +7,7 @@
package main
func main() {
- for x; y; z // ERROR "missing { after for clause|undefined"
+ for x; y; z // ERROR "missing .*{.* after for clause|undefined"
{
z // GCCGO_ERROR "undefined"
diff --git a/test/syntax/semi4.go b/test/syntax/semi4.go
index 00fa3f575..99c2d2256 100644
--- a/test/syntax/semi4.go
+++ b/test/syntax/semi4.go
@@ -8,7 +8,7 @@ package main
func main() {
for x // GCCGO_ERROR "undefined"
- { // ERROR "missing { after for clause"
+ { // ERROR "missing .*{.* after for clause"
z // GCCGO_ERROR "undefined"
diff --git a/test/tinyfin.go b/test/tinyfin.go
new file mode 100644
index 000000000..8fb109fc0
--- /dev/null
+++ b/test/tinyfin.go
@@ -0,0 +1,62 @@
+// run
+
+// Copyright 2014 The Go 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 finalizers work for tiny (combined) allocations.
+
+package main
+
+import (
+ "runtime"
+ "sync/atomic"
+ "time"
+)
+
+func main() {
+ // Does not work on 32-bits due to partially conservative GC.
+ // Try to enable when we have fully precise GC.
+ if runtime.GOARCH != "amd64" {
+ return
+ }
+ // Likewise for gccgo.
+ if runtime.Compiler == "gccgo" {
+ return
+ }
+ N := int32(100)
+ count := N
+ done := make([]bool, N)
+ for i := int32(0); i < N; i++ {
+ x := i // subject to tiny alloc
+ // the closure must be big enough to be combined
+ runtime.SetFinalizer(&x, func(p *int32) {
+ // Check that p points to the correct subobject of the tiny allocation.
+ // It's a bit tricky, because we can't capture another variable
+ // with the expected value (it would be combined as well).
+ if *p < 0 || *p >= N {
+ println("got", *p)
+ panic("corrupted")
+ }
+ if done[*p] {
+ println("got", *p)
+ panic("already finalized")
+ }
+ done[*p] = true
+ atomic.AddInt32(&count, -1)
+ })
+ }
+ for i := 0; i < 4; i++ {
+ runtime.GC()
+ time.Sleep(10 * time.Millisecond)
+ }
+ // Some of the finalizers may not be executed,
+ // if the outermost allocations are combined with something persistent.
+ // Currently 4 int32's are combined into a 16-byte block,
+ // ensure that most of them are finalized.
+ if count >= N/4 {
+ println(count, "out of", N, "finalizer are not called")
+ panic("not all finalizers are called")
+ }
+}
+
diff --git a/test/typecheck.go b/test/typecheck.go
index 239ceacc6..6f1204289 100644
--- a/test/typecheck.go
+++ b/test/typecheck.go
@@ -13,6 +13,6 @@ func mine(int b) int { // ERROR "undefined.*b"
}
func main() {
- mine()
- c = mine() // ERROR "undefined.*c" "cannot assign to c"
+ mine() // GCCGO_ERROR "not enough arguments"
+ c = mine() // ERROR "undefined.*c|not enough arguments"
}