aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorDan Willemsen <dwillemsen@google.com>2018-02-27 19:36:27 -0800
committerDan Willemsen <dwillemsen@google.com>2018-02-27 19:36:27 -0800
commite1b3b188ff03c41213dca621c46c39702d79f3ee (patch)
tree67ab03d7ee51c5fafa1602c28e0d9033a8e3f26d /test
parent3c27c3f6c42dbb890c67820f2897812e16f01be1 (diff)
downloadplatform_prebuilts_go_linux-x86-e1b3b188ff03c41213dca621c46c39702d79f3ee.tar.gz
platform_prebuilts_go_linux-x86-e1b3b188ff03c41213dca621c46c39702d79f3ee.tar.bz2
platform_prebuilts_go_linux-x86-e1b3b188ff03c41213dca621c46c39702d79f3ee.zip
Test: m -j blueprint_tools Change-Id: I12d0286a2978fcbafa50880625700ba69c4581d8
Diffstat (limited to 'test')
-rw-r--r--test/chan/sendstmt.go2
-rw-r--r--test/chancap.go43
-rw-r--r--test/closure3.dir/main.go283
-rw-r--r--test/closure3.go10
-rw-r--r--test/ddd1.go3
-rwxr-xr-xtest/errchk3
-rw-r--r--test/escape2.go2
-rw-r--r--test/escape2n.go15
-rw-r--r--test/escape4.go6
-rw-r--r--test/fixedbugs/bug289.go4
-rw-r--r--test/fixedbugs/bug388.go2
-rw-r--r--test/fixedbugs/bug487.go4
-rw-r--r--test/fixedbugs/bug503.go16
-rw-r--r--test/fixedbugs/bug504.dir/a.go7
-rw-r--r--test/fixedbugs/bug504.dir/b.go11
-rw-r--r--test/fixedbugs/bug504.dir/c.go9
-rw-r--r--test/fixedbugs/bug504.dir/main.go11
-rw-r--r--test/fixedbugs/bug504.go10
-rw-r--r--test/fixedbugs/bug505.go20
-rw-r--r--test/fixedbugs/issue13265.go15
-rw-r--r--test/fixedbugs/issue14006.go3
-rw-r--r--test/fixedbugs/issue14540.go20
-rw-r--r--test/fixedbugs/issue15747.go6
-rw-r--r--test/fixedbugs/issue15747b.go2
-rw-r--r--test/fixedbugs/issue18902.go12
-rw-r--r--test/fixedbugs/issue19137.go16
-rw-r--r--test/fixedbugs/issue19261.dir/p.go24
-rw-r--r--test/fixedbugs/issue19261.dir/q.go17
-rw-r--r--test/fixedbugs/issue19261.go7
-rw-r--r--test/fixedbugs/issue20250.go10
-rw-r--r--test/fixedbugs/issue20739.go16
-rw-r--r--test/fixedbugs/issue20812.go15
-rw-r--r--test/fixedbugs/issue21253.go27
-rw-r--r--test/fixedbugs/issue21256.go9
-rw-r--r--test/fixedbugs/issue21273.go28
-rw-r--r--test/fixedbugs/issue21317.go60
-rw-r--r--test/fixedbugs/issue21655.go62
-rw-r--r--test/fixedbugs/issue21687.go68
-rw-r--r--test/fixedbugs/issue21709.go37
-rw-r--r--test/fixedbugs/issue21770.go20
-rw-r--r--test/fixedbugs/issue21808.go17
-rw-r--r--test/fixedbugs/issue21808.out3
-rw-r--r--test/fixedbugs/issue21879.go37
-rw-r--r--test/fixedbugs/issue21879.out2
-rw-r--r--test/fixedbugs/issue21882.go9
-rw-r--r--test/fixedbugs/issue21887.go25
-rw-r--r--test/fixedbugs/issue21887.out2
-rw-r--r--test/fixedbugs/issue21963.go27
-rw-r--r--test/fixedbugs/issue21988.go17
-rw-r--r--test/fixedbugs/issue22063.go17
-rw-r--r--test/fixedbugs/issue22076.go25
-rw-r--r--test/fixedbugs/issue22083.go41
-rw-r--r--test/fixedbugs/issue22164.go26
-rw-r--r--test/fixedbugs/issue22198.go18
-rw-r--r--test/fixedbugs/issue22200.go20
-rw-r--r--test/fixedbugs/issue22200b.go28
-rw-r--r--test/fixedbugs/issue22351.go11
-rw-r--r--test/fixedbugs/issue22389.go18
-rw-r--r--test/fixedbugs/issue22429.go18
-rw-r--r--test/fixedbugs/issue22458.go26
-rw-r--r--test/fixedbugs/issue22581.go27
-rw-r--r--test/fixedbugs/issue22605.go26
-rw-r--r--test/fixedbugs/issue22660.go50
-rw-r--r--test/fixedbugs/issue22683.go30
-rw-r--r--test/fixedbugs/issue22683.out1
-rw-r--r--test/fixedbugs/issue22781.go29
-rw-r--r--test/fixedbugs/issue22794.go20
-rw-r--r--test/fixedbugs/issue22877.dir/p.go14
-rw-r--r--test/fixedbugs/issue22877.dir/p.s8
-rw-r--r--test/fixedbugs/issue22877.go7
-rw-r--r--test/fixedbugs/issue22881.go72
-rw-r--r--test/fixedbugs/issue22904.go19
-rw-r--r--test/fixedbugs/issue22941.dir/a.go7
-rw-r--r--test/fixedbugs/issue22941.dir/b.go30
-rw-r--r--test/fixedbugs/issue22941.dir/main.go15
-rw-r--r--test/fixedbugs/issue22941.go7
-rw-r--r--test/fixedbugs/issue22962.dir/a.go11
-rw-r--r--test/fixedbugs/issue22962.dir/b.go9
-rw-r--r--test/fixedbugs/issue22962.go7
-rw-r--r--test/fixedbugs/issue23093.go9
-rw-r--r--test/fixedbugs/issue23179.dir/a.go13
-rw-r--r--test/fixedbugs/issue23179.dir/b.go11
-rw-r--r--test/fixedbugs/issue23179.go7
-rw-r--r--test/fixedbugs/issue23305.go28
-rw-r--r--test/fixedbugs/issue23522.go46
-rw-r--r--test/fixedbugs/issue23545.go35
-rw-r--r--test/fixedbugs/issue23719.go42
-rw-r--r--test/fixedbugs/issue23812.go34
-rw-r--r--test/fixedbugs/issue4388.go56
-rw-r--r--test/fixedbugs/issue7525.go4
-rw-r--r--test/fixedbugs/issue7525d.go15
-rw-r--r--test/fixedbugs/issue7525e.go15
-rw-r--r--test/inline.go92
-rw-r--r--test/inline_callers.go8
-rw-r--r--test/intrinsic_atomic.go2
-rw-r--r--test/live.go51
-rw-r--r--test/live2.go11
-rw-r--r--test/live_syscall.go12
-rw-r--r--test/makechan.go34
-rw-r--r--test/makemap.go34
-rw-r--r--test/mergemul.go117
-rw-r--r--test/method2.go4
-rw-r--r--test/method6.go22
-rw-r--r--test/method7.go56
-rw-r--r--test/nilptr3.go7
-rw-r--r--test/nosplit.go43
-rw-r--r--test/notinheap3.go60
-rw-r--r--test/nowritebarrier.go15
-rw-r--r--test/print.go14
-rw-r--r--test/print.out10
-rw-r--r--test/range.go49
-rw-r--r--test/recover4.go2
-rw-r--r--test/rename1.go4
-rw-r--r--test/run.go58
-rw-r--r--test/shift1.go3
115 files changed, 2576 insertions, 158 deletions
diff --git a/test/chan/sendstmt.go b/test/chan/sendstmt.go
index c0f1a29f..d296a55c 100644
--- a/test/chan/sendstmt.go
+++ b/test/chan/sendstmt.go
@@ -5,7 +5,7 @@
// license that can be found in the LICENSE file.
// Test various parsing cases that are a little
-// different now that send is a statement, not a expression.
+// different now that send is a statement, not an expression.
package main
diff --git a/test/chancap.go b/test/chancap.go
index b3e40233..b08478a1 100644
--- a/test/chancap.go
+++ b/test/chancap.go
@@ -8,8 +8,17 @@
package main
+import (
+ "strings"
+ "unsafe"
+)
+
+type T chan int
+
+const ptrSize = unsafe.Sizeof((*byte)(nil))
+
func main() {
- c := make(chan int, 10)
+ c := make(T, 10)
if len(c) != 0 || cap(c) != 10 {
println("chan len/cap ", len(c), cap(c), " want 0 10")
panic("fail")
@@ -23,9 +32,39 @@ func main() {
panic("fail")
}
- c = make(chan int)
+ c = make(T)
if len(c) != 0 || cap(c) != 0 {
println("chan len/cap ", len(c), cap(c), " want 0 0")
panic("fail")
}
+
+ n := -1
+ shouldPanic("makechan: size out of range", func() { _ = make(T, n) })
+ shouldPanic("makechan: size out of range", func() { _ = make(T, int64(n)) })
+ if ptrSize == 8 {
+ n = 1 << 20
+ n <<= 20
+ shouldPanic("makechan: size out of range", func() { _ = make(T, n) })
+ n <<= 20
+ shouldPanic("makechan: size out of range", func() { _ = make(T, n) })
+ } else {
+ n = 1<<31 - 1
+ shouldPanic("makechan: size out of range", func() { _ = make(T, n) })
+ shouldPanic("makechan: size out of range", func() { _ = make(T, int64(n)) })
+ }
+}
+
+func shouldPanic(str string, f func()) {
+ defer func() {
+ err := recover()
+ if err == nil {
+ panic("did not panic")
+ }
+ s := err.(error).Error()
+ if !strings.Contains(s, str) {
+ panic("got panic " + s + ", want " + str)
+ }
+ }()
+
+ f()
}
diff --git a/test/closure3.dir/main.go b/test/closure3.dir/main.go
new file mode 100644
index 00000000..43643431
--- /dev/null
+++ b/test/closure3.dir/main.go
@@ -0,0 +1,283 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check correctness of various closure corner cases that
+// that are expected to be inlined
+
+package main
+
+var ok bool
+var sink int
+
+func main() {
+ {
+ if x := func() int { // ERROR "can inline main.func1"
+ return 1
+ }(); x != 1 { // ERROR "inlining call to main.func1"
+ panic("x != 1")
+ }
+ if x := func() int { // ERROR "can inline main.func2" "func literal does not escape"
+ return 1
+ }; x() != 1 { // ERROR "inlining call to main.func2"
+ panic("x() != 1")
+ }
+ }
+
+ {
+ if y := func(x int) int { // ERROR "can inline main.func3"
+ return x + 2
+ }(40); y != 42 { // ERROR "inlining call to main.func3"
+ panic("y != 42")
+ }
+ if y := func(x int) int { // ERROR "can inline main.func4" "func literal does not escape"
+ return x + 2
+ }; y(40) != 42 { // ERROR "inlining call to main.func4"
+ panic("y(40) != 42")
+ }
+ }
+
+ {
+ y := func(x int) int { // ERROR "can inline main.func5" "func literal does not escape"
+ return x + 2
+ }
+ y = func(x int) int { // ERROR "can inline main.func6" "func literal does not escape"
+ return x + 1
+ }
+ if y(40) != 41 {
+ panic("y(40) != 41")
+ }
+ }
+
+ {
+ func() { // ERROR "func literal does not escape"
+ y := func(x int) int { // ERROR "can inline main.func7.1" "func literal does not escape"
+ return x + 2
+ }
+ y = func(x int) int { // ERROR "can inline main.func7.2" "func literal does not escape"
+ return x + 1
+ }
+ if y(40) != 41 {
+ panic("y(40) != 41")
+ }
+ }()
+ }
+
+ {
+ y := func(x int) int { // ERROR "can inline main.func8" "func literal does not escape"
+ return x + 2
+ }
+ y, sink = func(x int) int { // ERROR "can inline main.func9" "func literal does not escape"
+ return x + 1
+ }, 42
+ if y(40) != 41 {
+ panic("y(40) != 41")
+ }
+ }
+
+ {
+ func() { // ERROR "func literal does not escape"
+ y := func(x int) int { // ERROR "can inline main.func10.1" "func literal does not escape"
+ return x + 2
+ }
+ y, sink = func(x int) int { // ERROR "can inline main.func10.2" "func literal does not escape"
+ return x + 1
+ }, 42
+ if y(40) != 41 {
+ panic("y(40) != 41")
+ }
+ }()
+ }
+
+ {
+ y := func(x int) int { // ERROR "can inline main.func11" "func literal does not escape"
+ return x + 2
+ }
+ y, sink = func() (func(int)int, int) { // ERROR "func literal does not escape"
+ return func(x int) int { // ERROR "can inline main.func12" "func literal escapes"
+ return x + 1
+ }, 42
+ }()
+ if y(40) != 41 {
+ panic("y(40) != 41")
+ }
+ }
+
+ {
+ func() { // ERROR "func literal does not escape"
+ y := func(x int) int { // ERROR "can inline main.func13.1" "func literal does not escape"
+ return x + 2
+ }
+ y, sink = func() (func(int) int, int) { // ERROR "func literal does not escape"
+ return func(x int) int { // ERROR "can inline main.func13.2" "func literal escapes"
+ return x + 1
+ }, 42
+ }()
+ if y(40) != 41 {
+ panic("y(40) != 41")
+ }
+ }()
+ }
+
+ {
+ y := func(x int) int { // ERROR "can inline main.func14" "func literal does not escape"
+ return x + 2
+ }
+ y, ok = map[int]func(int)int { // ERROR "does not escape"
+ 0: func (x int) int { return x + 1 }, // ERROR "can inline main.func15" "func literal escapes"
+ }[0]
+ if y(40) != 41 {
+ panic("y(40) != 41")
+ }
+ }
+
+ {
+ func() { // ERROR "func literal does not escape"
+ y := func(x int) int { // ERROR "can inline main.func16.1" "func literal does not escape"
+ return x + 2
+ }
+ y, ok = map[int]func(int) int{// ERROR "does not escape"
+ 0: func(x int) int { return x + 1 }, // ERROR "can inline main.func16.2" "func literal escapes"
+ }[0]
+ if y(40) != 41 {
+ panic("y(40) != 41")
+ }
+ }()
+ }
+
+ {
+ y := func(x int) int { // ERROR "can inline main.func17" "func literal does not escape"
+ return x + 2
+ }
+ y, ok = interface{}(func (x int) int { // ERROR "can inline main.func18" "does not escape"
+ return x + 1
+ }).(func(int)int)
+ if y(40) != 41 {
+ panic("y(40) != 41")
+ }
+ }
+
+ {
+ func() { // ERROR "func literal does not escape"
+ y := func(x int) int { // ERROR "can inline main.func19.1" "func literal does not escape"
+ return x + 2
+ }
+ y, ok = interface{}(func(x int) int { // ERROR "can inline main.func19.2" "does not escape"
+ return x + 1
+ }).(func(int) int)
+ if y(40) != 41 {
+ panic("y(40) != 41")
+ }
+ }()
+ }
+
+ {
+ x := 42
+ if y := func() int { // ERROR "can inline main.func20"
+ return x
+ }(); y != 42 { // ERROR "inlining call to main.func20"
+ panic("y != 42")
+ }
+ if y := func() int { // ERROR "can inline main.func21" "func literal does not escape"
+ return x
+ }; y() != 42 { // ERROR "inlining call to main.func21"
+ panic("y() != 42")
+ }
+ }
+
+ {
+ x := 42
+ if z := func(y int) int { // ERROR "func literal does not escape"
+ return func() int { // ERROR "can inline main.func22.1"
+ return x + y
+ }() // ERROR "inlining call to main.func22.1"
+ }(1); z != 43 {
+ panic("z != 43")
+ }
+ if z := func(y int) int { // ERROR "func literal does not escape"
+ return func() int { // ERROR "can inline main.func23.1"
+ return x + y
+ }() // ERROR "inlining call to main.func23.1"
+ }; z(1) != 43 {
+ panic("z(1) != 43")
+ }
+ }
+
+ {
+ a := 1
+ func() { // ERROR "func literal does not escape"
+ func() { // ERROR "can inline main.func24"
+ a = 2
+ }() // ERROR "inlining call to main.func24" "&a does not escape"
+ }()
+ if a != 2 {
+ panic("a != 2")
+ }
+ }
+
+ {
+ b := 2
+ func(b int) { // ERROR "func literal does not escape"
+ func() { // ERROR "can inline main.func25.1"
+ b = 3
+ }() // ERROR "inlining call to main.func25.1" "&b does not escape"
+ if b != 3 {
+ panic("b != 3")
+ }
+ }(b)
+ if b != 2 {
+ panic("b != 2")
+ }
+ }
+
+ {
+ c := 3
+ func() { // ERROR "func literal does not escape"
+ c = 4
+ func() { // ERROR "func literal does not escape"
+ if c != 4 {
+ panic("c != 4")
+ }
+ }()
+ }()
+ if c != 4 {
+ panic("c != 4")
+ }
+ }
+
+ {
+ a := 2
+ if r := func(x int) int { // ERROR "func literal does not escape"
+ b := 3
+ return func(y int) int { // ERROR "func literal does not escape"
+ c := 5
+ return func(z int) int { // ERROR "can inline main.func27.1.1"
+ return a*x + b*y + c*z
+ }(10) // ERROR "inlining call to main.func27.1.1"
+ }(100)
+ }(1000); r != 2350 {
+ panic("r != 2350")
+ }
+ }
+
+ {
+ a := 2
+ if r := func(x int) int { // ERROR "func literal does not escape"
+ b := 3
+ return func(y int) int { // ERROR "func literal does not escape"
+ c := 5
+ func(z int) { // ERROR "can inline main.func28.1.1"
+ a = a * x
+ b = b * y
+ c = c * z
+ }(10) // ERROR "inlining call to main.func28.1.1" "&a does not escape" "&b does not escape" "&c does not escape"
+ return a + c
+ }(100) + b
+ }(1000); r != 2350 {
+ panic("r != 2350")
+ }
+ if a != 2000 {
+ panic("a != 2000")
+ }
+ }
+}
diff --git a/test/closure3.go b/test/closure3.go
new file mode 100644
index 00000000..263d8fcb
--- /dev/null
+++ b/test/closure3.go
@@ -0,0 +1,10 @@
+// errorcheckandrundir -0 -m
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Check correctness of various closure corner cases that
+// that are expected to be inlined
+
+package ignored
diff --git a/test/ddd1.go b/test/ddd1.go
index 4284e321..b4ad80b6 100644
--- a/test/ddd1.go
+++ b/test/ddd1.go
@@ -53,8 +53,7 @@ func bad(args ...int) {
_ = new(int...) // ERROR "[.][.][.]"
n := 10
_ = make([]byte, n...) // ERROR "[.][.][.]"
- // TODO(rsc): enable after gofmt bug is fixed
- // _ = make([]byte, 10 ...) // error "[.][.][.]"
+ _ = make([]byte, 10 ...) // ERROR "[.][.][.]"
var x int
_ = unsafe.Pointer(&x...) // ERROR "[.][.][.]"
_ = unsafe.Sizeof(x...) // ERROR "[.][.][.]"
diff --git a/test/errchk b/test/errchk
index bc8ef19c..1cb57bb9 100755
--- a/test/errchk
+++ b/test/errchk
@@ -65,6 +65,9 @@ $out = join('', <CMD>);
close CMD;
+# Remove lines beginning with #, printed by go command to indicate package.
+@out = grep {!/^#/} @out;
+
if($exitcode != 0 && $? == 0) {
print STDERR "BUG: errchk: command succeeded unexpectedly\n";
print STDERR @out;
diff --git a/test/escape2.go b/test/escape2.go
index e10dbc2a..ef3d6a88 100644
--- a/test/escape2.go
+++ b/test/escape2.go
@@ -1204,7 +1204,7 @@ func foo126() {
// loopdepth 1
var i int // ERROR "moved to heap: i$"
func() { // ERROR "foo126 func literal does not escape$"
- px = &i // ERROR "&i escapes to heap$" "leaking closure reference i"
+ px = &i // ERROR "&i escapes to heap$" "leaking closure reference i"
}()
}
_ = px
diff --git a/test/escape2n.go b/test/escape2n.go
index 74f6f8dd..b1130d3c 100644
--- a/test/escape2n.go
+++ b/test/escape2n.go
@@ -1824,3 +1824,18 @@ func issue11387(x int) func() int {
copy(slice2, slice1)
return slice2[0]
}
+
+func issue12397(x, y int) { // ERROR "moved to heap: y$"
+ // x does not escape below, because all relevant code is dead.
+ if false {
+ gxx = &x
+ } else {
+ gxx = &y // ERROR "&y escapes to heap$"
+ }
+
+ if true {
+ gxx = &y // ERROR "&y escapes to heap$"
+ } else {
+ gxx = &x
+ }
+}
diff --git a/test/escape4.go b/test/escape4.go
index 69a54ac7..22a37c1d 100644
--- a/test/escape4.go
+++ b/test/escape4.go
@@ -22,9 +22,9 @@ func f1() {
// Escape analysis used to miss inlined code in closures.
- func() { // ERROR "func literal does not escape" "can inline f1.func1"
- p = alloc(3) // ERROR "inlining call to alloc" "&x escapes to heap" "moved to heap: x"
- }()
+ func() { // ERROR "can inline f1.func1"
+ p = alloc(3) // ERROR "inlining call to alloc"
+ }() // ERROR "inlining call to f1.func1" "inlining call to alloc" "&x escapes to heap" "moved to heap: x"
f = func() { // ERROR "func literal escapes to heap" "can inline f1.func2"
p = alloc(3) // ERROR "inlining call to alloc" "&x escapes to heap" "moved to heap: x"
diff --git a/test/fixedbugs/bug289.go b/test/fixedbugs/bug289.go
index a3f72955..3fc7fb2e 100644
--- a/test/fixedbugs/bug289.go
+++ b/test/fixedbugs/bug289.go
@@ -9,14 +9,14 @@
package main
func f1() {
- a, b := f() // ERROR "cannot assign|does not match"
+ a, b := f() // ERROR "assignment mismatch|does not match"
_ = a
_ = b
}
func f2() {
var a, b int
- a, b = f() // ERROR "cannot assign|does not match"
+ a, b = f() // ERROR "assignment mismatch|does not match"
_ = a
_ = b
}
diff --git a/test/fixedbugs/bug388.go b/test/fixedbugs/bug388.go
index af0c9d9c..2d508501 100644
--- a/test/fixedbugs/bug388.go
+++ b/test/fixedbugs/bug388.go
@@ -14,7 +14,7 @@ func foo(runtime.UintType, i int) { // ERROR "cannot declare name runtime.UintT
}
func bar(i int) {
- runtime.UintType := i // ERROR "cannot declare name runtime.UintType|non-name on left side|undefined identifier"
+ runtime.UintType := i // ERROR "non-name runtime.UintType|non-name on left side|undefined identifier"
println(runtime.UintType) // GCCGO_ERROR "invalid use of type|undefined identifier"
}
diff --git a/test/fixedbugs/bug487.go b/test/fixedbugs/bug487.go
index 60a4ea98..ab61a19a 100644
--- a/test/fixedbugs/bug487.go
+++ b/test/fixedbugs/bug487.go
@@ -14,8 +14,8 @@ func G() (int, int, int) {
}
func F() {
- a, b := G() // ERROR "cannot assign"
- a, b = G() // ERROR "cannot assign"
+ a, b := G() // ERROR "assignment mismatch"
+ a, b = G() // ERROR "assignment mismatch"
_, _ = a, b
}
diff --git a/test/fixedbugs/bug503.go b/test/fixedbugs/bug503.go
new file mode 100644
index 00000000..7bbc7981
--- /dev/null
+++ b/test/fixedbugs/bug503.go
@@ -0,0 +1,16 @@
+// compile
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// gccgo crashed compiling this file, due to failing to correctly emit
+// the type descriptor for a named alias.
+
+package p
+
+type entry = struct {
+ a, b, c int
+}
+
+var V entry
diff --git a/test/fixedbugs/bug504.dir/a.go b/test/fixedbugs/bug504.dir/a.go
new file mode 100644
index 00000000..ac0be937
--- /dev/null
+++ b/test/fixedbugs/bug504.dir/a.go
@@ -0,0 +1,7 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+type MyInt = int
diff --git a/test/fixedbugs/bug504.dir/b.go b/test/fixedbugs/bug504.dir/b.go
new file mode 100644
index 00000000..e8f8da9a
--- /dev/null
+++ b/test/fixedbugs/bug504.dir/b.go
@@ -0,0 +1,11 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package b
+
+import "./a"
+
+func F() a.MyInt {
+ return 0
+}
diff --git a/test/fixedbugs/bug504.dir/c.go b/test/fixedbugs/bug504.dir/c.go
new file mode 100644
index 00000000..5a6e8899
--- /dev/null
+++ b/test/fixedbugs/bug504.dir/c.go
@@ -0,0 +1,9 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package c
+
+import "./b"
+
+var V = b.F()
diff --git a/test/fixedbugs/bug504.dir/main.go b/test/fixedbugs/bug504.dir/main.go
new file mode 100644
index 00000000..bdbd95c7
--- /dev/null
+++ b/test/fixedbugs/bug504.dir/main.go
@@ -0,0 +1,11 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "./c"
+
+func main() {
+ println(c.V)
+}
diff --git a/test/fixedbugs/bug504.go b/test/fixedbugs/bug504.go
new file mode 100644
index 00000000..ae1f2e52
--- /dev/null
+++ b/test/fixedbugs/bug504.go
@@ -0,0 +1,10 @@
+// compiledir
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Gccgo mishandled a reference to a type alias in a package that was
+// not directly imported.
+
+package ignored
diff --git a/test/fixedbugs/bug505.go b/test/fixedbugs/bug505.go
new file mode 100644
index 00000000..062a0871
--- /dev/null
+++ b/test/fixedbugs/bug505.go
@@ -0,0 +1,20 @@
+// compile
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// gccgo crashed compiling this file with a failed conversion to the
+// alias type when constructing the composite literal.
+
+package p
+
+type I interface{ M() }
+type A = I
+type S struct {
+ f A
+}
+
+func F(i I) S {
+ return S{f: i}
+}
diff --git a/test/fixedbugs/issue13265.go b/test/fixedbugs/issue13265.go
new file mode 100644
index 00000000..3036ba7c
--- /dev/null
+++ b/test/fixedbugs/issue13265.go
@@ -0,0 +1,15 @@
+// errorcheck -0 -race
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 13265: nil pointer deref.
+
+package p
+
+func f() {
+ var c chan chan chan int
+ for ; ; <-<-<-c {
+ }
+}
diff --git a/test/fixedbugs/issue14006.go b/test/fixedbugs/issue14006.go
index d69bdd48..02041cc2 100644
--- a/test/fixedbugs/issue14006.go
+++ b/test/fixedbugs/issue14006.go
@@ -50,7 +50,10 @@ func f() {
labelname: // ERROR "missing statement after label"
case false:
}
+}
+func g() {
+ var z bool
switch {
case z:
labelname: // ERROR "label labelname defined and not used"
diff --git a/test/fixedbugs/issue14540.go b/test/fixedbugs/issue14540.go
new file mode 100644
index 00000000..62b17a04
--- /dev/null
+++ b/test/fixedbugs/issue14540.go
@@ -0,0 +1,20 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f(x int) {
+ switch x {
+ case 0:
+ fallthrough
+ ; // ok
+ case 1:
+ fallthrough // ERROR "fallthrough statement out of place"
+ {}
+ case 2:
+ fallthrough // ERROR "cannot fallthrough"
+ }
+}
diff --git a/test/fixedbugs/issue15747.go b/test/fixedbugs/issue15747.go
index 836d0eab..decabc75 100644
--- a/test/fixedbugs/issue15747.go
+++ b/test/fixedbugs/issue15747.go
@@ -1,4 +1,4 @@
-// errorcheck -0 -live
+// errorcheck -0 -live -d=eagerwb
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
@@ -7,6 +7,10 @@
// Issue 15747: liveness analysis was marking heap-escaped params live too much,
// and worse was using the wrong bitmap bits to do so.
+// TODO(austin): This expects function calls to the write barrier, so
+// we enable the legacy eager write barrier. Fix this once the
+// buffered write barrier works on all arches.
+
package p
var global *[]byte
diff --git a/test/fixedbugs/issue15747b.go b/test/fixedbugs/issue15747b.go
index 9620d3d0..bdb2a940 100644
--- a/test/fixedbugs/issue15747b.go
+++ b/test/fixedbugs/issue15747b.go
@@ -4,7 +4,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Issue 15747: If a ODCL is dropped, for example when inlining,
+// Issue 15747: If an ODCL is dropped, for example when inlining,
// then it's easy to end up not initializing the '&x' pseudo-variable
// to point to an actual allocation. The liveness analysis will detect
// this and abort the computation, so this test just checks that the
diff --git a/test/fixedbugs/issue18902.go b/test/fixedbugs/issue18902.go
index f5bca16a..78c92187 100644
--- a/test/fixedbugs/issue18902.go
+++ b/test/fixedbugs/issue18902.go
@@ -50,13 +50,16 @@ func main() {
testarch := os.Getenv("TESTARCH") // Targets other platform in test compilation.
debug := os.Getenv("TESTDEBUG") != "" // Output the relevant assembly language.
- cmd := exec.Command("go", "build", "-gcflags", "-S", "fixedbugs/issue18902b.go")
+ cmd := exec.Command("go", "tool", "compile", "-S", "fixedbugs/issue18902b.go")
var buf bytes.Buffer
cmd.Stdout = &buf
cmd.Stderr = &buf
cmd.Env = os.Environ()
- updateEnv(&cmd.Env, "GOARCH", testarch)
+ if testarch != "" {
+ updateEnv(&cmd.Env, "GOARCH", testarch)
+ updateEnv(&cmd.Env, "GOOS", "linux") // Simplify multi-arch testing
+ }
err := cmd.Run()
if err != nil {
@@ -89,8 +92,9 @@ func main() {
i = strings.Index(line, beforeLineNumber)
if i < 0 {
// Done reading lines
- if scannedCount < 200 { // When test was written, 251 lines observed on amd64
- fmt.Printf("Scanned only %d lines, was expecting more than 200", scannedCount)
+ const minLines = 150
+ if scannedCount <= minLines { // When test was written, 251 lines observed on amd64; arm64 now obtains 184
+ fmt.Printf("Scanned only %d lines, was expecting more than %d\n", int(scannedCount), minLines)
return
}
// Note: when test was written, before changes=92, after=50 (was 62 w/o rematerialization NoXPos in *Value.copyInto())
diff --git a/test/fixedbugs/issue19137.go b/test/fixedbugs/issue19137.go
index 946f029b..0539a850 100644
--- a/test/fixedbugs/issue19137.go
+++ b/test/fixedbugs/issue19137.go
@@ -33,3 +33,19 @@ func zero() ([20]byte, [20]byte) {
_ = x
return [20]byte{}, [20]byte{} // the second return value is not 8-byte aligned to SP
}
+
+// Issue 21992: unaligned offset between 256 and 504 and handled
+// incorrectly.
+type T2 struct {
+ a [257]byte
+ // fields below are not 8-, 4-, 2-byte aligned
+ b [8]byte
+ c [4]byte
+ d [2]byte
+}
+
+func f2(x *T2) {
+ x.b = [8]byte{}
+ x.c = [4]byte{}
+ x.d = [2]byte{}
+}
diff --git a/test/fixedbugs/issue19261.dir/p.go b/test/fixedbugs/issue19261.dir/p.go
new file mode 100644
index 00000000..1c44d8a3
--- /dev/null
+++ b/test/fixedbugs/issue19261.dir/p.go
@@ -0,0 +1,24 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func F() { // ERROR "can inline F"
+ print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+}
+
+func G() {
+ F() // ERROR "inlining call to F"
+ print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+}
diff --git a/test/fixedbugs/issue19261.dir/q.go b/test/fixedbugs/issue19261.dir/q.go
new file mode 100644
index 00000000..9f3550ab
--- /dev/null
+++ b/test/fixedbugs/issue19261.dir/q.go
@@ -0,0 +1,17 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package q
+
+import "./p"
+
+func H() {
+ p.F() // ERROR "inlining call to p.F"
+ print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+ print(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
+}
diff --git a/test/fixedbugs/issue19261.go b/test/fixedbugs/issue19261.go
new file mode 100644
index 00000000..61cff6e1
--- /dev/null
+++ b/test/fixedbugs/issue19261.go
@@ -0,0 +1,7 @@
+// errorcheckdir -0 -m
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue20250.go b/test/fixedbugs/issue20250.go
index f24710a0..525192a4 100644
--- a/test/fixedbugs/issue20250.go
+++ b/test/fixedbugs/issue20250.go
@@ -1,4 +1,4 @@
-// errorcheck -0 -live -d=compilelater
+// errorcheck -0 -live -l -d=compilelater,eagerwb
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
@@ -8,6 +8,10 @@
// due to propagation of addrtaken to outer variables for
// closure variables.
+// TODO(austin): This expects function calls to the write barrier, so
+// we enable the legacy eager write barrier. Fix this once the
+// buffered write barrier works on all arches.
+
package p
type T struct {
@@ -16,8 +20,8 @@ type T struct {
func f(a T) { // ERROR "live at entry to f: a"
var e interface{}
- func() { // ERROR "live at entry to f.func1: &e a"
- e = a.s // ERROR "live at call to convT2Estring: &e a" "live at call to writebarrierptr: a"
+ func() { // ERROR "live at entry to f.func1: a &e"
+ e = a.s // ERROR "live at call to convT2Estring: a &e" "live at call to writebarrierptr: a"
}() // ERROR "live at call to f.func1: e$"
// Before the fix, both a and e were live at the previous line.
_ = e
diff --git a/test/fixedbugs/issue20739.go b/test/fixedbugs/issue20739.go
new file mode 100644
index 00000000..b71a25dc
--- /dev/null
+++ b/test/fixedbugs/issue20739.go
@@ -0,0 +1,16 @@
+// compile
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func F() {
+ var x struct {
+ x *int
+ w [1e9][1e9][1e9][0]*int
+ y *int
+ }
+ println(&x)
+}
diff --git a/test/fixedbugs/issue20812.go b/test/fixedbugs/issue20812.go
new file mode 100644
index 00000000..0175eede
--- /dev/null
+++ b/test/fixedbugs/issue20812.go
@@ -0,0 +1,15 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f() {
+ _ = int("1") // ERROR "cannot convert"
+ _ = bool(0) // ERROR "cannot convert"
+ _ = bool("false") // ERROR "cannot convert"
+ _ = int(false) // ERROR "cannot convert"
+ _ = string(true) // ERROR "cannot convert"
+}
diff --git a/test/fixedbugs/issue21253.go b/test/fixedbugs/issue21253.go
new file mode 100644
index 00000000..3531b2b8
--- /dev/null
+++ b/test/fixedbugs/issue21253.go
@@ -0,0 +1,27 @@
+// compile
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Gccgo crashed compiling this code due to failing to finalize
+// interfaces in the right order.
+
+package p
+
+type s1 struct {
+ f m
+ I
+}
+
+type m interface {
+ Mm(*s2)
+}
+
+type s2 struct {
+ *s1
+}
+
+type I interface {
+ MI()
+}
diff --git a/test/fixedbugs/issue21256.go b/test/fixedbugs/issue21256.go
new file mode 100644
index 00000000..3d361247
--- /dev/null
+++ b/test/fixedbugs/issue21256.go
@@ -0,0 +1,9 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+var main = func() {} // ERROR "must be func"
diff --git a/test/fixedbugs/issue21273.go b/test/fixedbugs/issue21273.go
new file mode 100644
index 00000000..7a790d14
--- /dev/null
+++ b/test/fixedbugs/issue21273.go
@@ -0,0 +1,28 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+type T0 T0 // ERROR "invalid recursive type"
+type _ map[T0]int
+
+type T1 struct{ T1 } // ERROR "invalid recursive type"
+type _ map[T1]int
+
+func f() {
+ type T2 T2 // ERROR "invalid recursive type"
+ type _ map[T2]int
+}
+
+func g() {
+ type T3 struct{ T3 } // ERROR "invalid recursive type"
+ type _ map[T3]int
+}
+
+func h() {
+ type T4 struct{ m map[T4]int } // ERROR "invalid map key"
+ type _ map[T4]int // ERROR "invalid map key"
+}
diff --git a/test/fixedbugs/issue21317.go b/test/fixedbugs/issue21317.go
new file mode 100644
index 00000000..ae0e0b55
--- /dev/null
+++ b/test/fixedbugs/issue21317.go
@@ -0,0 +1,60 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// As of "Mon 6 Nov 2017", run.go doesn't yet have proper
+// column matching so instead match the output manually
+// by exec-ing
+
+package main
+
+import (
+ "fmt"
+ "io/ioutil"
+ "log"
+ "os"
+ "os/exec"
+ "runtime"
+ "strings"
+)
+
+func main() {
+ if runtime.Compiler != "gc" || runtime.GOOS == "nacl" {
+ return
+ }
+
+ f, err := ioutil.TempFile("", "issue21317.go")
+ if err != nil {
+ log.Fatal(err)
+ }
+ fmt.Fprintf(f, `
+package main
+
+import "fmt"
+
+func main() {
+ n, err := fmt.Println(1)
+}
+`)
+ f.Close()
+ defer os.RemoveAll(f.Name())
+
+ // compile and test output
+ cmd := exec.Command("go", "tool", "compile", f.Name())
+ out, err := cmd.CombinedOutput()
+ if err == nil {
+ log.Fatalf("expected cmd/compile to fail")
+ }
+ wantErrs := []string{
+ "7:9: n declared and not used",
+ "7:12: err declared and not used",
+ }
+ outStr := string(out)
+ for _, want := range wantErrs {
+ if !strings.Contains(outStr, want) {
+ log.Fatalf("failed to match %q\noutput: %q", want, outStr)
+ }
+ }
+}
diff --git a/test/fixedbugs/issue21655.go b/test/fixedbugs/issue21655.go
new file mode 100644
index 00000000..66d4e3a7
--- /dev/null
+++ b/test/fixedbugs/issue21655.go
@@ -0,0 +1,62 @@
+// compile
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Make sure assembly offsets don't get too large.
+
+// To trigger issue21655, the index offset needs to be small
+// enough to fit into an int32 (to get rewritten to an ADDQconst)
+// but large enough to overflow an int32 after multiplying by the stride.
+
+package main
+
+func f1(a []int64, i int64) int64 {
+ return a[i+1<<30]
+}
+func f2(a []int32, i int64) int32 {
+ return a[i+1<<30]
+}
+func f3(a []int16, i int64) int16 {
+ return a[i+1<<30]
+}
+func f4(a []int8, i int64) int8 {
+ return a[i+1<<31]
+}
+func f5(a []float64, i int64) float64 {
+ return a[i+1<<30]
+}
+func f6(a []float32, i int64) float32 {
+ return a[i+1<<30]
+}
+
+// Note: Before the fix for issue 21655, f{1,2,5,6} made
+// the compiler crash. f3 silently generated the wrong
+// code, using an offset of -1<<31 instead of 1<<31.
+// (This is due to the assembler accepting offsets
+// like 0x80000000 and silently using them as
+// signed 32 bit offsets.)
+// f4 was ok, but testing it can't hurt.
+
+func f7(ss []*string, i int) string {
+ const offset = 3 << 29 // 3<<29 * 4 = 3<<31 = 1<<31 mod 1<<32.
+ if i > offset {
+ return *ss[i-offset]
+ }
+ return ""
+}
+func f8(ss []*string, i int) string {
+ const offset = 3<<29 + 10
+ if i > offset {
+ return *ss[i-offset]
+ }
+ return ""
+}
+func f9(ss []*string, i int) string {
+ const offset = 3<<29 - 10
+ if i > offset {
+ return *ss[i-offset]
+ }
+ return ""
+}
diff --git a/test/fixedbugs/issue21687.go b/test/fixedbugs/issue21687.go
new file mode 100644
index 00000000..9b4c03fe
--- /dev/null
+++ b/test/fixedbugs/issue21687.go
@@ -0,0 +1,68 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 21687: cmd/compile evaluates x twice in "x op= y", which was
+// detectable if evaluating y affects x.
+
+package main
+
+func ptrs() (int, int) {
+ one := 1
+ two := 2
+
+ x := &one
+ *x += func() int {
+ x = &two
+ return 0
+ }()
+
+ return one, two
+}
+
+func slices() (int, int) {
+ one := []int{1}
+ two := []int{2}
+
+ x := one
+ x[0] += func() int {
+ x = two
+ return 0
+ }()
+
+ return one[0], two[0]
+}
+
+func maps() (int, int) {
+ one := map[int]int{0: 1}
+ two := map[int]int{0: 2}
+
+ x := one
+ x[0] += func() int {
+ x = two
+ return 0
+ }()
+
+ return one[0], two[0]
+}
+
+var tests = [...]func() (int, int){
+ ptrs,
+ slices,
+ maps,
+}
+
+func main() {
+ bad := 0
+ for i, f := range tests {
+ if a, b := f(); a+b != 3 {
+ println(i, a, b)
+ bad++
+ }
+ }
+ if bad != 0 {
+ panic(bad)
+ }
+}
diff --git a/test/fixedbugs/issue21709.go b/test/fixedbugs/issue21709.go
new file mode 100644
index 00000000..bf5d9d23
--- /dev/null
+++ b/test/fixedbugs/issue21709.go
@@ -0,0 +1,37 @@
+// errorcheck -0 -l -m
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 21709: range expression overly escapes.
+
+package p
+
+type S struct{}
+
+func (s *S) Inc() {} // ERROR "\(\*S\).Inc s does not escape"
+var N int
+
+func F1() {
+ var s S // ERROR "moved to heap: s"
+ for i := 0; i < N; i++ {
+ fs := []func(){ // ERROR "F1 \[\]func\(\) literal does not escape"
+ s.Inc, // ERROR "F1 s.Inc does not escape" "s escapes to heap"
+ }
+ for _, f := range fs {
+ f()
+ }
+ }
+}
+
+func F2() {
+ var s S // ERROR "moved to heap: s"
+ for i := 0; i < N; i++ {
+ for _, f := range []func(){ // ERROR "F2 \[\]func\(\) literal does not escape"
+ s.Inc, // ERROR "F2 s.Inc does not escape" "s escapes to heap"
+ } {
+ f()
+ }
+ }
+}
diff --git a/test/fixedbugs/issue21770.go b/test/fixedbugs/issue21770.go
new file mode 100644
index 00000000..2f07d640
--- /dev/null
+++ b/test/fixedbugs/issue21770.go
@@ -0,0 +1,20 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 21770: gccgo incorrectly accepts "p.f = 0" where p is **struct
+
+package p
+
+type PP **struct{ f int }
+
+func f() {
+ // anonymous type
+ var p **struct{ f int }
+ p.f = 0 // ERROR "field"
+ // named type
+ var p2 PP
+ p2.f = 0 // ERROR "field"
+}
diff --git a/test/fixedbugs/issue21808.go b/test/fixedbugs/issue21808.go
new file mode 100644
index 00000000..d146200e
--- /dev/null
+++ b/test/fixedbugs/issue21808.go
@@ -0,0 +1,17 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Make sure println() prints a blank line.
+
+package main
+
+import "fmt"
+
+func main() {
+ fmt.Println("A")
+ println()
+ fmt.Println("B")
+}
diff --git a/test/fixedbugs/issue21808.out b/test/fixedbugs/issue21808.out
new file mode 100644
index 00000000..655da036
--- /dev/null
+++ b/test/fixedbugs/issue21808.out
@@ -0,0 +1,3 @@
+A
+
+B
diff --git a/test/fixedbugs/issue21879.go b/test/fixedbugs/issue21879.go
new file mode 100644
index 00000000..1029ca04
--- /dev/null
+++ b/test/fixedbugs/issue21879.go
@@ -0,0 +1,37 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "runtime"
+)
+
+func main() {
+ println(caller().frame.Function)
+
+ // Used to erroneously print "main.call.name" instead of
+ // "main.main".
+ println(caller().name())
+}
+
+func caller() call {
+ var pcs [3]uintptr
+ n := runtime.Callers(1, pcs[:])
+ frames := runtime.CallersFrames(pcs[:n])
+ frame, _ := frames.Next()
+ frame, _ = frames.Next()
+
+ return call{frame: frame}
+}
+
+type call struct {
+ frame runtime.Frame
+}
+
+func (c call) name() string {
+ return c.frame.Function
+}
diff --git a/test/fixedbugs/issue21879.out b/test/fixedbugs/issue21879.out
new file mode 100644
index 00000000..066f1a83
--- /dev/null
+++ b/test/fixedbugs/issue21879.out
@@ -0,0 +1,2 @@
+main.main
+main.main
diff --git a/test/fixedbugs/issue21882.go b/test/fixedbugs/issue21882.go
new file mode 100644
index 00000000..f77e0469
--- /dev/null
+++ b/test/fixedbugs/issue21882.go
@@ -0,0 +1,9 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type T [2]T // ERROR "invalid recursive type"
diff --git a/test/fixedbugs/issue21887.go b/test/fixedbugs/issue21887.go
new file mode 100644
index 00000000..9e3e91fc
--- /dev/null
+++ b/test/fixedbugs/issue21887.go
@@ -0,0 +1,25 @@
+// cmpout
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 21887: println(^uint(0)) fails to compile
+
+package main
+
+import "strconv"
+
+func main() {
+ if strconv.IntSize == 32 {
+ println(^uint(0))
+ } else {
+ println(^uint32(0))
+ }
+
+ if strconv.IntSize == 64 {
+ println(^uint(0))
+ } else {
+ println(^uint64(0))
+ }
+}
diff --git a/test/fixedbugs/issue21887.out b/test/fixedbugs/issue21887.out
new file mode 100644
index 00000000..664b67d7
--- /dev/null
+++ b/test/fixedbugs/issue21887.out
@@ -0,0 +1,2 @@
+4294967295
+18446744073709551615
diff --git a/test/fixedbugs/issue21963.go b/test/fixedbugs/issue21963.go
new file mode 100644
index 00000000..996bd63d
--- /dev/null
+++ b/test/fixedbugs/issue21963.go
@@ -0,0 +1,27 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "fmt"
+ "runtime"
+)
+
+//go:noinline
+func f(x []int32, y *int8) int32 {
+ c := int32(int16(*y))
+ runtime.GC()
+ return x[0] * c
+}
+
+func main() {
+ var x = [1]int32{5}
+ var y int8 = -1
+ if got, want := f(x[:], &y), int32(-5); got != want {
+ panic(fmt.Sprintf("wanted %d, got %d", want, got))
+ }
+}
diff --git a/test/fixedbugs/issue21988.go b/test/fixedbugs/issue21988.go
new file mode 100644
index 00000000..850e0398
--- /dev/null
+++ b/test/fixedbugs/issue21988.go
@@ -0,0 +1,17 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 21988: panic on switch case with invalid value
+
+package p
+
+const X = Wrong(0) // ERROR "undefined: Wrong"
+
+func _() {
+ switch 0 {
+ case X:
+ }
+}
diff --git a/test/fixedbugs/issue22063.go b/test/fixedbugs/issue22063.go
new file mode 100644
index 00000000..bfdb2e00
--- /dev/null
+++ b/test/fixedbugs/issue22063.go
@@ -0,0 +1,17 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 22063: panic on interface switch case with invalid name
+
+package p
+
+const X = Wrong(0) // ERROR "undefined: Wrong"
+
+func _() {
+ switch interface{}(nil) {
+ case X:
+ }
+}
diff --git a/test/fixedbugs/issue22076.go b/test/fixedbugs/issue22076.go
new file mode 100644
index 00000000..5d628b96
--- /dev/null
+++ b/test/fixedbugs/issue22076.go
@@ -0,0 +1,25 @@
+// compile
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 22076: Couldn't use ":=" to declare names that refer to
+// dot-imported symbols.
+
+package p
+
+import . "bytes"
+
+var _ Reader // use "bytes" import
+
+func _() {
+ Buffer := 0
+ _ = Buffer
+}
+
+func _() {
+ for Buffer := range []int{} {
+ _ = Buffer
+ }
+}
diff --git a/test/fixedbugs/issue22083.go b/test/fixedbugs/issue22083.go
new file mode 100644
index 00000000..a385102d
--- /dev/null
+++ b/test/fixedbugs/issue22083.go
@@ -0,0 +1,41 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// The compiler was panicking on the wrong line number, where
+// the panic was occurring in an inlined call.
+
+package main
+
+import (
+ "runtime/debug"
+ "strings"
+)
+
+type Wrapper struct {
+ a []int
+}
+
+func (w Wrapper) Get(i int) int {
+ return w.a[i]
+}
+
+func main() {
+ defer func() {
+ e := recover()
+ if e == nil {
+ panic("bounds check didn't fail")
+ }
+ stk := string(debug.Stack())
+ if !strings.Contains(stk, "issue22083.go:40") {
+ panic("wrong stack trace: " + stk)
+ }
+ }()
+ foo := Wrapper{a: []int{0, 1, 2}}
+ _ = foo.Get(0)
+ _ = foo.Get(1)
+ _ = foo.Get(2)
+ _ = foo.Get(3) // stack trace should mention this line
+}
diff --git a/test/fixedbugs/issue22164.go b/test/fixedbugs/issue22164.go
new file mode 100644
index 00000000..fad78e23
--- /dev/null
+++ b/test/fixedbugs/issue22164.go
@@ -0,0 +1,26 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test error recovery after missing closing parentheses in lists.
+
+package p
+
+func f() {
+ x := f(g() // ERROR "unexpected newline"
+ y := 1
+}
+
+func g() {
+}
+
+func h() {
+ x := f(g() // ERROR "unexpected newline"
+}
+
+func i() {
+ x := []int{1, 2, 3 // ERROR "unexpected newline"
+ y := 0
+} \ No newline at end of file
diff --git a/test/fixedbugs/issue22198.go b/test/fixedbugs/issue22198.go
new file mode 100644
index 00000000..c874c1ca
--- /dev/null
+++ b/test/fixedbugs/issue22198.go
@@ -0,0 +1,18 @@
+// compile
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package issue22198
+
+func f(a *bool, b bool) {
+ if b {
+ return
+ }
+ c := '\n'
+ if b {
+ c = ' '
+ }
+ *a = c == '\n'
+}
diff --git a/test/fixedbugs/issue22200.go b/test/fixedbugs/issue22200.go
new file mode 100644
index 00000000..66b9538e
--- /dev/null
+++ b/test/fixedbugs/issue22200.go
@@ -0,0 +1,20 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f1(x *[1<<30 - 1e6]byte) byte {
+ for _, b := range *x {
+ return b
+ }
+ return 0
+}
+func f2(x *[1<<30 + 1e6]byte) byte { // ERROR "stack frame too large"
+ for _, b := range *x {
+ return b
+ }
+ return 0
+}
diff --git a/test/fixedbugs/issue22200b.go b/test/fixedbugs/issue22200b.go
new file mode 100644
index 00000000..8d4515eb
--- /dev/null
+++ b/test/fixedbugs/issue22200b.go
@@ -0,0 +1,28 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !386,!amd64p32,!arm,!mips,!mipsle
+
+package p
+
+func f3(x *[1 << 31]byte) byte { // ERROR "stack frame too large"
+ for _, b := range *x {
+ return b
+ }
+ return 0
+}
+func f4(x *[1 << 32]byte) byte { // ERROR "stack frame too large"
+ for _, b := range *x {
+ return b
+ }
+ return 0
+}
+func f5(x *[1 << 33]byte) byte { // ERROR "stack frame too large"
+ for _, b := range *x {
+ return b
+ }
+ return 0
+}
diff --git a/test/fixedbugs/issue22351.go b/test/fixedbugs/issue22351.go
new file mode 100644
index 00000000..e46a0fb2
--- /dev/null
+++ b/test/fixedbugs/issue22351.go
@@ -0,0 +1,11 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "unsafe"
+
+const _ = uint64(unsafe.Offsetof(T{}.F)) // ERROR "undefined"
diff --git a/test/fixedbugs/issue22389.go b/test/fixedbugs/issue22389.go
new file mode 100644
index 00000000..706b4494
--- /dev/null
+++ b/test/fixedbugs/issue22389.go
@@ -0,0 +1,18 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type Foo struct{}
+
+func (f *Foo) Call(cb func(*Foo)) {
+ cb(f)
+}
+
+func main() {
+ f := &Foo{}
+ f.Call(func(f) {}) // ERROR "f is not a type"
+}
diff --git a/test/fixedbugs/issue22429.go b/test/fixedbugs/issue22429.go
new file mode 100644
index 00000000..289b434a
--- /dev/null
+++ b/test/fixedbugs/issue22429.go
@@ -0,0 +1,18 @@
+// compile
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Make sure SSA->assembly pass can handle SP as an index register.
+
+package p
+
+type T struct {
+ a,b,c,d float32
+}
+
+func f(a *[8]T, i,j,k int) float32 {
+ b := *a
+ return b[i].a + b[j].b + b[k].c
+}
diff --git a/test/fixedbugs/issue22458.go b/test/fixedbugs/issue22458.go
new file mode 100644
index 00000000..5c899295
--- /dev/null
+++ b/test/fixedbugs/issue22458.go
@@ -0,0 +1,26 @@
+// compile
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Make sure KeepAlive introduces a use of the spilled variable.
+
+package main
+
+import "runtime"
+
+type node struct {
+ next *node
+}
+
+var x bool
+
+func main() {
+ var head *node
+ for x {
+ head = &node{head}
+ }
+
+ runtime.KeepAlive(head)
+}
diff --git a/test/fixedbugs/issue22581.go b/test/fixedbugs/issue22581.go
new file mode 100644
index 00000000..2b637f2e
--- /dev/null
+++ b/test/fixedbugs/issue22581.go
@@ -0,0 +1,27 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+func f() {
+ if i := g()); i == j { // ERROR "unexpected \)"
+ }
+
+ if i == g()] { // ERROR "unexpected \]"
+ }
+
+ switch i := g()); i { // ERROR "unexpected \)"
+ }
+
+ switch g()] { // ERROR "unexpected \]"
+ }
+
+ for i := g()); i < y; { // ERROR "unexpected \)"
+ }
+
+ for g()] { // ERROR "unexpected \]"
+ }
+}
diff --git a/test/fixedbugs/issue22605.go b/test/fixedbugs/issue22605.go
new file mode 100644
index 00000000..9e726f35
--- /dev/null
+++ b/test/fixedbugs/issue22605.go
@@ -0,0 +1,26 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// We were picking up a special noalg type from typelinks.
+
+package main
+
+import "reflect"
+
+func f(m map[string]int) int {
+ return m["a"]
+}
+
+func g(m map[[8]string]int) int {
+ t := reflect.ArrayOf(8, reflect.TypeOf(""))
+ a := reflect.New(t).Elem()
+ return m[a.Interface().([8]string)]
+}
+
+func main() {
+ m := map[[8]string]int{}
+ g(m)
+}
diff --git a/test/fixedbugs/issue22660.go b/test/fixedbugs/issue22660.go
new file mode 100644
index 00000000..48686fef
--- /dev/null
+++ b/test/fixedbugs/issue22660.go
@@ -0,0 +1,50 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "runtime"
+ "strings"
+)
+
+func main() {
+ if runtime.GOOS == "nacl" {
+ return // no file system available on builders
+ }
+
+ f, err := ioutil.TempFile("", "issue22660.go")
+ if err != nil {
+ log.Fatal(err)
+ }
+ f.Close()
+ defer os.Remove(f.Name())
+
+ // path must appear in error messages even if we strip them with -trimpath
+ path := filepath.Join("users", "xxx", "go")
+ var src bytes.Buffer
+ fmt.Fprintf(&src, "//line %s:1\n", filepath.Join(path, "foo.go"))
+
+ if err := ioutil.WriteFile(f.Name(), src.Bytes(), 0660); err != nil {
+ log.Fatal(err)
+ }
+
+ out, err := exec.Command("go", "tool", "compile", fmt.Sprintf("-trimpath=%s", path), f.Name()).CombinedOutput()
+ if err == nil {
+ log.Fatalf("expected compiling %s to fail", f.Name())
+ }
+
+ if !strings.HasPrefix(string(out), path) {
+ log.Fatalf("expected full path (%s) in error message, got:\n%s", path, out)
+ }
+}
diff --git a/test/fixedbugs/issue22683.go b/test/fixedbugs/issue22683.go
new file mode 100644
index 00000000..a59a0eda
--- /dev/null
+++ b/test/fixedbugs/issue22683.go
@@ -0,0 +1,30 @@
+// cmpout
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "fmt"
+)
+
+type foo struct {
+ bar [1]*int
+}
+
+func main() {
+ ch := make(chan foo, 2)
+ var a int
+ var b [1]*int
+ b[0] = &a
+ ch <- foo{bar: b}
+ close(ch)
+
+ for v := range ch {
+ for i := 0; i < 1; i++ {
+ fmt.Println(v.bar[0] != nil)
+ }
+ }
+}
diff --git a/test/fixedbugs/issue22683.out b/test/fixedbugs/issue22683.out
new file mode 100644
index 00000000..27ba77dd
--- /dev/null
+++ b/test/fixedbugs/issue22683.out
@@ -0,0 +1 @@
+true
diff --git a/test/fixedbugs/issue22781.go b/test/fixedbugs/issue22781.go
new file mode 100644
index 00000000..5ad82398
--- /dev/null
+++ b/test/fixedbugs/issue22781.go
@@ -0,0 +1,29 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "runtime/debug"
+
+type T struct {
+ // >= 16 bytes to avoid tiny alloc.
+ a, b int
+}
+
+func main() {
+ debug.SetGCPercent(1)
+ for i := 0; i < 100000; i++ {
+ m := make(map[*T]struct{}, 0)
+ for j := 0; j < 20; j++ {
+ // During the call to mapassign_fast64, the key argument
+ // was incorrectly treated as a uint64. If the stack was
+ // scanned during that call, the only pointer to k was
+ // missed, leading to *k being collected prematurely.
+ k := new(T)
+ m[k] = struct{}{}
+ }
+ }
+}
diff --git a/test/fixedbugs/issue22794.go b/test/fixedbugs/issue22794.go
new file mode 100644
index 00000000..c7e9eb12
--- /dev/null
+++ b/test/fixedbugs/issue22794.go
@@ -0,0 +1,20 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+type it struct {
+ Floats bool
+ inner string
+}
+
+func main() {
+ i1 := it{Floats: true}
+ if i1.floats { // ERROR "(type it .* field or method floats, but does have Floats)"
+ }
+ i2 := &it{floats: false} // ERROR "(but does have Floats)"
+ _ = &it{InneR: "foo"} // ERROR "(but does have inner)"
+}
diff --git a/test/fixedbugs/issue22877.dir/p.go b/test/fixedbugs/issue22877.dir/p.go
new file mode 100644
index 00000000..fc86cb9e
--- /dev/null
+++ b/test/fixedbugs/issue22877.dir/p.go
@@ -0,0 +1,14 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+type S struct{ i int }
+type SS = S
+
+func sub()
+
+func main() {
+ sub()
+}
diff --git a/test/fixedbugs/issue22877.dir/p.s b/test/fixedbugs/issue22877.dir/p.s
new file mode 100644
index 00000000..8b14358c
--- /dev/null
+++ b/test/fixedbugs/issue22877.dir/p.s
@@ -0,0 +1,8 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include "go_asm.h"
+
+TEXT ·sub(SB), 0, $0
+ RET
diff --git a/test/fixedbugs/issue22877.go b/test/fixedbugs/issue22877.go
new file mode 100644
index 00000000..284b6807
--- /dev/null
+++ b/test/fixedbugs/issue22877.go
@@ -0,0 +1,7 @@
+// builddir
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue22881.go b/test/fixedbugs/issue22881.go
new file mode 100644
index 00000000..61e99a28
--- /dev/null
+++ b/test/fixedbugs/issue22881.go
@@ -0,0 +1,72 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test to make sure RHS is evaluated before map insert is started.
+// The RHS panics in all of these cases.
+
+package main
+
+import "fmt"
+
+func main() {
+ for i, f := range []func(map[int]int){
+ f0, f1, f2, f3, f4, f5, f6, f7,
+ } {
+ m := map[int]int{}
+ func() { // wrapper to scope the defer.
+ defer func() {
+ recover()
+ }()
+ f(m) // Will panic. Shouldn't modify m.
+ fmt.Printf("RHS didn't panic, case f%d\n", i)
+ }()
+ if len(m) != 0 {
+ fmt.Printf("map insert happened, case f%d\n", i)
+ }
+ }
+}
+
+func f0(m map[int]int) {
+ var p *int
+ m[0] = *p
+}
+
+func f1(m map[int]int) {
+ var p *int
+ m[0] += *p
+}
+
+func f2(m map[int]int) {
+ var p *int
+ sink, m[0] = sink, *p
+}
+
+func f3(m map[int]int) {
+ var p *chan int
+ m[0], sink = <-(*p)
+}
+
+func f4(m map[int]int) {
+ var p *interface{}
+ m[0], sink = (*p).(int)
+}
+
+func f5(m map[int]int) {
+ var p *map[int]int
+ m[0], sink = (*p)[0]
+}
+
+func f6(m map[int]int) {
+ var z int
+ m[0] /= z
+}
+
+func f7(m map[int]int) {
+ var a []int
+ m[0] = a[0]
+}
+
+var sink bool
diff --git a/test/fixedbugs/issue22904.go b/test/fixedbugs/issue22904.go
new file mode 100644
index 00000000..46cb7c04
--- /dev/null
+++ b/test/fixedbugs/issue22904.go
@@ -0,0 +1,19 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 22904: Make sure the compiler emits a proper error message about
+// invalid recursive types rather than crashing.
+
+package p
+
+type a struct{ b }
+type b struct{ a } // ERROR "invalid recursive type"
+
+var x interface{}
+
+func f() {
+ x = a{}
+}
diff --git a/test/fixedbugs/issue22941.dir/a.go b/test/fixedbugs/issue22941.dir/a.go
new file mode 100644
index 00000000..7a4ede43
--- /dev/null
+++ b/test/fixedbugs/issue22941.dir/a.go
@@ -0,0 +1,7 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package q
+
+type P int
diff --git a/test/fixedbugs/issue22941.dir/b.go b/test/fixedbugs/issue22941.dir/b.go
new file mode 100644
index 00000000..87d59a67
--- /dev/null
+++ b/test/fixedbugs/issue22941.dir/b.go
@@ -0,0 +1,30 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+import q "./a"
+
+type T struct {
+ X *q.P
+}
+
+func F(in, out *T) {
+ *out = *in
+ if in.X != nil {
+ in, out := &in.X, &out.X
+ if *in == nil {
+ *out = nil
+ } else {
+ *out = new(q.P)
+ **out = **in
+ }
+ }
+ return
+}
+
+//go:noinline
+func G(x, y *T) {
+ F(x, y)
+}
diff --git a/test/fixedbugs/issue22941.dir/main.go b/test/fixedbugs/issue22941.dir/main.go
new file mode 100644
index 00000000..84666adf
--- /dev/null
+++ b/test/fixedbugs/issue22941.dir/main.go
@@ -0,0 +1,15 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import p "./b"
+
+var G int
+
+func main() {
+ if G == 101 {
+ p.G(nil, nil)
+ }
+}
diff --git a/test/fixedbugs/issue22941.go b/test/fixedbugs/issue22941.go
new file mode 100644
index 00000000..c3732c31
--- /dev/null
+++ b/test/fixedbugs/issue22941.go
@@ -0,0 +1,7 @@
+// rundir
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue22962.dir/a.go b/test/fixedbugs/issue22962.dir/a.go
new file mode 100644
index 00000000..7257d7df
--- /dev/null
+++ b/test/fixedbugs/issue22962.dir/a.go
@@ -0,0 +1,11 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+func F() {
+ if x := 0; false {
+ _ = x
+ }
+}
diff --git a/test/fixedbugs/issue22962.dir/b.go b/test/fixedbugs/issue22962.dir/b.go
new file mode 100644
index 00000000..e1568c8f
--- /dev/null
+++ b/test/fixedbugs/issue22962.dir/b.go
@@ -0,0 +1,9 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package b
+
+import "a"
+
+var V = func() { a.F() }
diff --git a/test/fixedbugs/issue22962.go b/test/fixedbugs/issue22962.go
new file mode 100644
index 00000000..8000a522
--- /dev/null
+++ b/test/fixedbugs/issue22962.go
@@ -0,0 +1,7 @@
+// compiledir
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue23093.go b/test/fixedbugs/issue23093.go
new file mode 100644
index 00000000..2fd7d5ff
--- /dev/null
+++ b/test/fixedbugs/issue23093.go
@@ -0,0 +1,9 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+var f = func() { f() } // ERROR "initialization loop"
diff --git a/test/fixedbugs/issue23179.dir/a.go b/test/fixedbugs/issue23179.dir/a.go
new file mode 100644
index 00000000..3d2816fc
--- /dev/null
+++ b/test/fixedbugs/issue23179.dir/a.go
@@ -0,0 +1,13 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+type Large struct {
+ x [256]int
+}
+
+func F(x int, _ int, _ bool, _ Large) int {
+ return x
+}
diff --git a/test/fixedbugs/issue23179.dir/b.go b/test/fixedbugs/issue23179.dir/b.go
new file mode 100644
index 00000000..bec3d15e
--- /dev/null
+++ b/test/fixedbugs/issue23179.dir/b.go
@@ -0,0 +1,11 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package b
+
+import "a"
+
+func G(x int) int {
+ return a.F(x, 1, false, a.Large{})
+}
diff --git a/test/fixedbugs/issue23179.go b/test/fixedbugs/issue23179.go
new file mode 100644
index 00000000..8000a522
--- /dev/null
+++ b/test/fixedbugs/issue23179.go
@@ -0,0 +1,7 @@
+// compiledir
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ignored
diff --git a/test/fixedbugs/issue23305.go b/test/fixedbugs/issue23305.go
new file mode 100644
index 00000000..28f400c5
--- /dev/null
+++ b/test/fixedbugs/issue23305.go
@@ -0,0 +1,28 @@
+// run
+
+// Copyright 2018 The Go 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 mask1(a, b uint64) uint64 {
+ op1 := int32(a)
+ op2 := int32(b)
+ return uint64(uint32(op1 / op2))
+}
+
+var mask2 = mask1
+
+func main() {
+ res1 := mask1(0x1, 0xfffffffeffffffff)
+ res2 := mask2(0x1, 0xfffffffeffffffff)
+ if res1 != 0xffffffff {
+ println("got", res1, "want", 0xffffffff)
+ panic("FAIL")
+ }
+ if res2 != 0xffffffff {
+ println("got", res2, "want", 0xffffffff)
+ panic("FAIL")
+ }
+}
diff --git a/test/fixedbugs/issue23522.go b/test/fixedbugs/issue23522.go
new file mode 100644
index 00000000..cace86c8
--- /dev/null
+++ b/test/fixedbugs/issue23522.go
@@ -0,0 +1,46 @@
+// run
+
+// Copyright 2018 The Go 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"
+)
+
+type S struct {
+ u int64
+ n int32
+}
+
+func F1(f float64) *S {
+ s := f
+ pf := math.Copysign(f, 1)
+ u := math.Floor(pf)
+ return &S{
+ u: int64(math.Copysign(u, s)),
+ n: int32(math.Copysign((pf-u)*1e9, s)),
+ }
+}
+
+func F2(f float64) *S {
+ s := f
+ f = math.Copysign(f, 1)
+ u := math.Floor(f)
+ return &S{
+ u: int64(math.Copysign(u, s)),
+ n: int32(math.Copysign((f-u)*1e9, s)),
+ }
+}
+
+func main() {
+ s1 := F1(-1)
+ s2 := F2(-1)
+ if *s1 != *s2 {
+ println("F1:", s1.u, s1.n)
+ println("F2:", s2.u, s2.n)
+ panic("different")
+ }
+}
diff --git a/test/fixedbugs/issue23545.go b/test/fixedbugs/issue23545.go
new file mode 100644
index 00000000..24485c11
--- /dev/null
+++ b/test/fixedbugs/issue23545.go
@@ -0,0 +1,35 @@
+// run
+
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build gccgo
+
+// Issue 23545: gccgo didn't lower array comparison to
+// proper equality function in some case.
+// TODO: build only on gccgo for now, as it hits issue
+// #23546.
+
+package main
+
+func main() {
+ if a := Get(); a != dummyID(1234) {
+ panic("FAIL")
+ }
+}
+
+func dummyID(x int) [Size]interface{} {
+ var out [Size]interface{}
+ out[0] = x
+ return out
+}
+
+const Size = 32
+
+type OutputID [Size]interface{}
+
+//go:noinline
+func Get() OutputID {
+ return dummyID(1234)
+}
diff --git a/test/fixedbugs/issue23719.go b/test/fixedbugs/issue23719.go
new file mode 100644
index 00000000..c97e6363
--- /dev/null
+++ b/test/fixedbugs/issue23719.go
@@ -0,0 +1,42 @@
+// run
+
+// Copyright 2018 The Go 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() {
+ v1 := [2]int32{-1, 88}
+ v2 := [2]int32{-1, 99}
+ if v1 == v2 {
+ panic("bad comparison")
+ }
+
+ w1 := [2]int16{-1, 88}
+ w2 := [2]int16{-1, 99}
+ if w1 == w2 {
+ panic("bad comparison")
+ }
+ x1 := [4]int16{-1, 88, 88, 88}
+ x2 := [4]int16{-1, 99, 99, 99}
+ if x1 == x2 {
+ panic("bad comparison")
+ }
+
+ a1 := [2]int8{-1, 88}
+ a2 := [2]int8{-1, 99}
+ if a1 == a2 {
+ panic("bad comparison")
+ }
+ b1 := [4]int8{-1, 88, 88, 88}
+ b2 := [4]int8{-1, 99, 99, 99}
+ if b1 == b2 {
+ panic("bad comparison")
+ }
+ c1 := [8]int8{-1, 88, 88, 88, 88, 88, 88, 88}
+ c2 := [8]int8{-1, 99, 99, 99, 99, 99, 99, 99}
+ if c1 == c2 {
+ panic("bad comparison")
+ }
+}
diff --git a/test/fixedbugs/issue23812.go b/test/fixedbugs/issue23812.go
new file mode 100644
index 00000000..0a40deb2
--- /dev/null
+++ b/test/fixedbugs/issue23812.go
@@ -0,0 +1,34 @@
+// run
+
+// Copyright 2018 The Go 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() {
+ want := int32(0x3edae8)
+ got := foo(1)
+ if want != got {
+ panic(fmt.Sprintf("want %x, got %x", want, got))
+ }
+}
+
+func foo(a int32) int32 {
+ return shr1(int32(shr2(int64(0x14ff6e2207db5d1f), int(a))), 4)
+}
+
+func shr1(n int32, m int) int32 { return n >> uint(m) }
+
+func shr2(n int64, m int) int64 {
+ if m < 0 {
+ m = -m
+ }
+ if m >= 64 {
+ return n
+ }
+
+ return n >> uint(m)
+}
diff --git a/test/fixedbugs/issue4388.go b/test/fixedbugs/issue4388.go
deleted file mode 100644
index 5bb05eb4..00000000
--- a/test/fixedbugs/issue4388.go
+++ /dev/null
@@ -1,56 +0,0 @@
-// 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 5 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(5)
- var t *T
- var c io.Closer = t
- c.Close()
-}
-
-func f2() {
- defer checkLine(5)
- 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/issue7525.go b/test/fixedbugs/issue7525.go
index 6e695931..fcfab723 100644
--- a/test/fixedbugs/issue7525.go
+++ b/test/fixedbugs/issue7525.go
@@ -11,7 +11,5 @@ 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"
+ a [unsafe.Sizeof(x.a)]int // ERROR "array bound|typechecking loop|invalid expression"
}
diff --git a/test/fixedbugs/issue7525d.go b/test/fixedbugs/issue7525d.go
new file mode 100644
index 00000000..141d6752
--- /dev/null
+++ b/test/fixedbugs/issue7525d.go
@@ -0,0 +1,15 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 7525: self-referential array types.
+
+package main
+
+import "unsafe"
+
+var x struct {
+ b [unsafe.Offsetof(x.b)]int // ERROR "array bound|typechecking loop|invalid array"
+}
diff --git a/test/fixedbugs/issue7525e.go b/test/fixedbugs/issue7525e.go
new file mode 100644
index 00000000..c13194ca
--- /dev/null
+++ b/test/fixedbugs/issue7525e.go
@@ -0,0 +1,15 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Issue 7525: self-referential array types.
+
+package main
+
+import "unsafe"
+
+var x struct {
+ c [unsafe.Alignof(x.c)]int // ERROR "array bound|typechecking loop|invalid array"
+}
diff --git a/test/inline.go b/test/inline.go
index 773b047c..25532304 100644
--- a/test/inline.go
+++ b/test/inline.go
@@ -9,7 +9,10 @@
package foo
-import "unsafe"
+import (
+ "errors"
+ "unsafe"
+)
func add2(p *byte, n uintptr) *byte { // ERROR "can inline add2" "leaking param: p to result"
return (*byte)(add1(unsafe.Pointer(p), n)) // ERROR "inlining call to add1"
@@ -46,6 +49,83 @@ func j(x int) int { // ERROR "can inline j"
}
}
+var somethingWrong error = errors.New("something went wrong")
+
+// local closures can be inlined
+func l(x, y int) (int, int, error) {
+ e := func(err error) (int, int, error) { // ERROR "can inline l.func1" "func literal does not escape" "leaking param: err to result"
+ return 0, 0, err
+ }
+ if x == y {
+ e(somethingWrong) // ERROR "inlining call to l.func1"
+ }
+ return y, x, nil
+}
+
+// any re-assignment prevents closure inlining
+func m() int {
+ foo := func() int { return 1 } // ERROR "can inline m.func1" "func literal does not escape"
+ x := foo()
+ foo = func() int { return 2 } // ERROR "can inline m.func2" "func literal does not escape"
+ return x + foo()
+}
+
+// address taking prevents closure inlining
+func n() int {
+ foo := func() int { return 1 } // ERROR "can inline n.func1" "func literal does not escape"
+ bar := &foo // ERROR "&foo does not escape"
+ x := (*bar)() + foo()
+ return x
+}
+
+// make sure assignment inside closure is detected
+func o() int {
+ foo := func() int { return 1 } // ERROR "can inline o.func1" "func literal does not escape"
+ func(x int) { // ERROR "func literal does not escape"
+ if x > 10 {
+ foo = func() int { return 2 } // ERROR "can inline o.func2" "func literal escapes"
+ }
+ }(11)
+ return foo()
+}
+
+func p() int {
+ return func() int { return 42 }() // ERROR "can inline p.func1" "inlining call to p.func1"
+}
+
+func q(x int) int {
+ foo := func() int { return x * 2 } // ERROR "can inline q.func1" "q func literal does not escape"
+ return foo() // ERROR "inlining call to q.func1"
+}
+
+func r(z int) int {
+ foo := func(x int) int { // ERROR "can inline r.func1" "r func literal does not escape"
+ return x + z
+ }
+ bar := func(x int) int { // ERROR "r func literal does not escape"
+ return x + func(y int) int { // ERROR "can inline r.func2.1"
+ return 2*y + x*z
+ }(x) // ERROR "inlining call to r.func2.1"
+ }
+ return foo(42) + bar(42) // ERROR "inlining call to r.func1"
+}
+
+func s0(x int) int {
+ foo := func() { // ERROR "can inline s0.func1" "s0 func literal does not escape"
+ x = x + 1
+ }
+ foo() // ERROR "inlining call to s0.func1" "&x does not escape"
+ return x
+}
+
+func s1(x int) int {
+ foo := func() int { // ERROR "can inline s1.func1" "s1 func literal does not escape"
+ return x
+ }
+ x = x + 1
+ return foo() // ERROR "inlining call to s1.func1" "&x does not escape"
+}
+
// can't currently inline functions with a break statement
func switchBreak(x, y int) int {
var n int
@@ -72,3 +152,13 @@ func switchType(x interface{}) int { // ERROR "switchType x does not escape"
return 0
}
}
+
+type T struct{}
+
+func (T) meth(int, int) {} // ERROR "can inline T.meth"
+
+func k() (T, int, int) { return T{}, 0, 0 } // ERROR "can inline k"
+
+func _() { // ERROR "can inline _"
+ T.meth(k()) // ERROR "inlining call to k" "inlining call to T.meth"
+}
diff --git a/test/inline_callers.go b/test/inline_callers.go
index fb6ff6c7..6df68619 100644
--- a/test/inline_callers.go
+++ b/test/inline_callers.go
@@ -1,4 +1,4 @@
-// run -gcflags -l=4
+// run -gcflags=-l=4
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
@@ -7,7 +7,7 @@
package main
import (
- "log"
+ "fmt"
"runtime"
)
@@ -83,13 +83,13 @@ func main() {
frames := testCallers(i)
expected := expectedFrames[i]
if !same(frames, expected) {
- log.Fatalf("testCallers(%d):\n got %v\n want %v", i, frames, expected)
+ fmt.Printf("testCallers(%d):\n got %v\n want %v\n", i, frames, expected)
}
frames = testCallersFrames(i)
expected = allFrames[i:]
if !same(frames, expected) {
- log.Fatalf("testCallersFrames(%d):\n got %v\n want %v", i, frames, expected)
+ fmt.Printf("testCallersFrames(%d):\n got %v\n want %v\n", i, frames, expected)
}
}
}
diff --git a/test/intrinsic_atomic.go b/test/intrinsic_atomic.go
index dd765a0f..a90056e1 100644
--- a/test/intrinsic_atomic.go
+++ b/test/intrinsic_atomic.go
@@ -1,5 +1,5 @@
// errorcheck -0 -d=ssa/intrinsics/debug
-// +build amd64 arm64
+// +build amd64 arm64 mips mipsle mips64 mips64le ppc64 ppc64le s390x
// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
diff --git a/test/live.go b/test/live.go
index ef988a05..e54336ea 100644
--- a/test/live.go
+++ b/test/live.go
@@ -239,15 +239,6 @@ func f14() {
func g14() string
-func f15() {
- var x string
- _ = &x
- x = g15() // ERROR "live at call to g15: x$"
- printstring(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
@@ -384,10 +375,9 @@ func f25(b bool) {
return
}
var x string
- _ = &x
- x = g15() // ERROR "live at call to g15: x$"
- printstring(x) // ERROR "live at call to printstring: x$"
-} // ERROR "live at call to deferreturn: x$"
+ x = g14()
+ printstring(x)
+}
func g25()
@@ -473,22 +463,30 @@ func f29(b bool) {
}
// copy of array of pointers should die at end of range loop
+var pstructarr [10]pstruct
-var ptrarr [10]*int
+// Struct size choosen to make pointer to element in pstructarr
+// not computable by strength reduction.
+type pstruct struct {
+ intp *int
+ _ [8]byte
+}
func f30(b bool) {
- // two live temps during print(p):
- // the copy of ptrarr and the internal iterator pointer.
+ // two live temps during printintpointer(p):
+ // in the copy of p.intp and
+ // the internal iterator pointer if a pointer to pstruct in pstructarr
+ // can not be easily computed by strength reduction.
if b {
- for _, p := range ptrarr {
- printintpointer(p) // ERROR "live at call to printintpointer: .autotmp_[0-9]+ .autotmp_[0-9]+$"
+ for _, p := range pstructarr {
+ printintpointer(p.intp) // ERROR "live at call to printintpointer: .autotmp_[0-9]+ .autotmp_[0-9]+$"
}
}
- for _, p := range ptrarr {
- printintpointer(p) // ERROR "live at call to printintpointer: .autotmp_[0-9]+ .autotmp_[0-9]+$"
+ for _, p := range pstructarr {
+ printintpointer(p.intp) // ERROR "live at call to printintpointer: .autotmp_[0-9]+ .autotmp_[0-9]+$"
}
- for _, p := range ptrarr {
- printintpointer(p) // ERROR "live at call to printintpointer: .autotmp_[0-9]+ .autotmp_[0-9]+$"
+ for _, p := range pstructarr {
+ printintpointer(p.intp) // ERROR "live at call to printintpointer: .autotmp_[0-9]+ .autotmp_[0-9]+$"
}
}
@@ -641,9 +639,12 @@ type T40 struct {
m map[int]int
}
+//go:noescape
+func useT40(*T40)
+
func newT40() *T40 {
ret := T40{}
- ret.m = make(map[int]int) // ERROR "live at call to makemap: &ret$"
+ ret.m = make(map[int]int, 42) // ERROR "live at call to makemap: &ret$"
return &ret
}
@@ -655,10 +656,10 @@ func bad40() {
func good40() {
ret := T40{}
- ret.m = make(map[int]int) // ERROR "live at call to makemap: .autotmp_[0-9]+ ret$"
+ ret.m = make(map[int]int) // ERROR "live at call to fastrand: .autotmp_[0-9]+ ret$"
t := &ret
printnl() // ERROR "live at call to printnl: .autotmp_[0-9]+ ret$"
- _ = t
+ useT40(t) // ERROR "live at call to useT40: .autotmp_[0-9]+ ret$"
}
func ddd1(x, y *int) { // ERROR "live at entry to ddd1: x y$"
diff --git a/test/live2.go b/test/live2.go
index 6138d369..cc1b0b7a 100644
--- a/test/live2.go
+++ b/test/live2.go
@@ -14,26 +14,29 @@ package main
func printnl()
+//go:noescape
+func useT40(*T40)
+
type T40 struct {
m map[int]int
}
func newT40() *T40 {
ret := T40{}
- ret.m = make(map[int]int) // ERROR "live at call to makemap: &ret$"
+ ret.m = make(map[int]int, 42) // ERROR "live at call to makemap: &ret$"
return &ret
}
func bad40() {
t := newT40() // ERROR "live at call to makemap: .autotmp_[0-9]+ ret$"
printnl() // ERROR "live at call to printnl: .autotmp_[0-9]+ ret$"
- _ = t
+ useT40(t) // ERROR "live at call to useT40: .autotmp_[0-9]+ ret$"
}
func good40() {
ret := T40{}
- ret.m = make(map[int]int) // ERROR "live at call to makemap: .autotmp_[0-9]+ ret$"
+ ret.m = make(map[int]int, 42) // ERROR "live at call to makemap: .autotmp_[0-9]+ ret$"
t := &ret
printnl() // ERROR "live at call to printnl: .autotmp_[0-9]+ ret$"
- _ = t
+ useT40(t) // ERROR "live at call to useT40: .autotmp_[0-9]+ ret$"
}
diff --git a/test/live_syscall.go b/test/live_syscall.go
index f693e935..6d954653 100644
--- a/test/live_syscall.go
+++ b/test/live_syscall.go
@@ -26,3 +26,15 @@ func h() {
var v int
syscall.Syscall(0, 1, uintptr(unsafe.Pointer(&v)), 2) // ERROR "live at call to Syscall: .?autotmp" "h &v does not escape"
}
+
+func i() {
+ var t int
+ p := unsafe.Pointer(&t) // ERROR "i &t does not escape"
+ f(uintptr(p)) // ERROR "live at call to f: .?autotmp"
+}
+
+func j() {
+ var v int
+ p := unsafe.Pointer(&v) // ERROR "j &v does not escape"
+ syscall.Syscall(0, 1, uintptr(p), 2) // ERROR "live at call to Syscall: .?autotmp"
+}
diff --git a/test/makechan.go b/test/makechan.go
new file mode 100644
index 00000000..0ac38c4b
--- /dev/null
+++ b/test/makechan.go
@@ -0,0 +1,34 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Ensure that typed non-integer, negative and to large
+// values are not accepted as size argument in make for
+// channels.
+
+package main
+
+type T chan byte
+
+var sink T
+
+func main() {
+ sink = make(T, -1) // ERROR "negative buffer argument in make.*"
+ sink = make(T, uint64(1<<63)) // ERROR "buffer argument too large in make.*"
+
+ sink = make(T, 0.5) // ERROR "constant 0.5 truncated to integer"
+ sink = make(T, 1.0)
+ sink = make(T, float32(1.0)) // ERROR "non-integer buffer argument in make.*"
+ sink = make(T, float64(1.0)) // ERROR "non-integer buffer argument in make.*"
+ sink = make(T, 1.0)
+ sink = make(T, float32(1.0)) // ERROR "non-integer buffer argument in make.*"
+ sink = make(T, float64(1.0)) // ERROR "non-integer buffer argument in make.*"
+ sink = make(T, 1+0i)
+ sink = make(T, complex64(1+0i)) // ERROR "non-integer buffer argument in make.*"
+ sink = make(T, complex128(1+0i)) // ERROR "non-integer buffer argument in make.*"
+ sink = make(T, 1+0i)
+ sink = make(T, complex64(1+0i)) // ERROR "non-integer buffer argument in make.*"
+ sink = make(T, complex128(1+0i)) // ERROR "non-integer buffer argument in make.*"
+}
diff --git a/test/makemap.go b/test/makemap.go
new file mode 100644
index 00000000..60983c0d
--- /dev/null
+++ b/test/makemap.go
@@ -0,0 +1,34 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Ensure that typed non-integer, negative and too large
+// values are not accepted as size argument in make for
+// maps.
+
+package main
+
+type T map[int]int
+
+var sink T
+
+func main() {
+ sink = make(T, -1) // ERROR "negative size argument in make.*"
+ sink = make(T, uint64(1<<63)) // ERROR "size argument too large in make.*"
+
+ sink = make(T, 0.5) // ERROR "constant 0.5 truncated to integer"
+ sink = make(T, 1.0)
+ sink = make(T, float32(1.0)) // ERROR "non-integer size argument in make.*"
+ sink = make(T, float64(1.0)) // ERROR "non-integer size argument in make.*"
+ sink = make(T, 1.0)
+ sink = make(T, float32(1.0)) // ERROR "non-integer size argument in make.*"
+ sink = make(T, float64(1.0)) // ERROR "non-integer size argument in make.*"
+ sink = make(T, 1+0i)
+ sink = make(T, complex64(1+0i)) // ERROR "non-integer size argument in make.*"
+ sink = make(T, complex128(1+0i)) // ERROR "non-integer size argument in make.*"
+ sink = make(T, 1+0i)
+ sink = make(T, complex64(1+0i)) // ERROR "non-integer size argument in make.*"
+ sink = make(T, complex128(1+0i)) // ERROR "non-integer size argument in make.*"
+}
diff --git a/test/mergemul.go b/test/mergemul.go
new file mode 100644
index 00000000..a23115b6
--- /dev/null
+++ b/test/mergemul.go
@@ -0,0 +1,117 @@
+// runoutput
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import "fmt"
+
+// Check that expressions like (c*n + d*(n+k)) get correctly merged by
+// the compiler into (c+d)*n + d*k (with c+d and d*k computed at
+// compile time).
+//
+// The merging is performed by a combination of the multiplication
+// merge rules
+// (c*n + d*n) -> (c+d)*n
+// and the distributive multiplication rules
+// c * (d+x) -> c*d + c*x
+
+// Generate a MergeTest that looks like this:
+//
+// a8, b8 = m1*n8 + m2*(n8+k), (m1+m2)*n8 + m2*k
+// if a8 != b8 {
+// // print error msg and panic
+// }
+func makeMergeAddTest(m1, m2, k int, size string) string {
+
+ model := " a" + size + ", b" + size
+ model += fmt.Sprintf(" = %%d*n%s + %%d*(n%s+%%d), (%%d+%%d)*n%s + (%%d*%%d)", size, size, size)
+
+ test := fmt.Sprintf(model, m1, m2, k, m1, m2, m2, k)
+ test += fmt.Sprintf(`
+ if a%s != b%s {
+ fmt.Printf("MergeAddTest(%d, %d, %d, %s) failed\n")
+ fmt.Printf("%%d != %%d\n", a%s, b%s)
+ panic("FAIL")
+ }
+`, size, size, m1, m2, k, size, size, size)
+ return test + "\n"
+}
+
+// Check that expressions like (c*n - d*(n+k)) get correctly merged by
+// the compiler into (c-d)*n - d*k (with c-d and d*k computed at
+// compile time).
+//
+// The merging is performed by a combination of the multiplication
+// merge rules
+// (c*n - d*n) -> (c-d)*n
+// and the distributive multiplication rules
+// c * (d-x) -> c*d - c*x
+
+// Generate a MergeTest that looks like this:
+//
+// a8, b8 = m1*n8 - m2*(n8+k), (m1-m2)*n8 - m2*k
+// if a8 != b8 {
+// // print error msg and panic
+// }
+func makeMergeSubTest(m1, m2, k int, size string) string {
+
+ model := " a" + size + ", b" + size
+ model += fmt.Sprintf(" = %%d*n%s - %%d*(n%s+%%d), (%%d-%%d)*n%s - (%%d*%%d)", size, size, size)
+
+ test := fmt.Sprintf(model, m1, m2, k, m1, m2, m2, k)
+ test += fmt.Sprintf(`
+ if a%s != b%s {
+ fmt.Printf("MergeSubTest(%d, %d, %d, %s) failed\n")
+ fmt.Printf("%%d != %%d\n", a%s, b%s)
+ panic("FAIL")
+ }
+`, size, size, m1, m2, k, size, size, size)
+ return test + "\n"
+}
+
+func makeAllSizes(m1, m2, k int) string {
+ var tests string
+ tests += makeMergeAddTest(m1, m2, k, "8")
+ tests += makeMergeAddTest(m1, m2, k, "16")
+ tests += makeMergeAddTest(m1, m2, k, "32")
+ tests += makeMergeAddTest(m1, m2, k, "64")
+ tests += makeMergeSubTest(m1, m2, k, "8")
+ tests += makeMergeSubTest(m1, m2, k, "16")
+ tests += makeMergeSubTest(m1, m2, k, "32")
+ tests += makeMergeSubTest(m1, m2, k, "64")
+ tests += "\n"
+ return tests
+}
+
+func main() {
+ fmt.Println(`package main
+
+import "fmt"
+
+var n8 int8 = 42
+var n16 int16 = 42
+var n32 int32 = 42
+var n64 int64 = 42
+
+func main() {
+ var a8, b8 int8
+ var a16, b16 int16
+ var a32, b32 int32
+ var a64, b64 int64
+`)
+
+ fmt.Println(makeAllSizes(03, 05, 0)) // 3*n + 5*n
+ fmt.Println(makeAllSizes(17, 33, 0))
+ fmt.Println(makeAllSizes(80, 45, 0))
+ fmt.Println(makeAllSizes(32, 64, 0))
+
+ fmt.Println(makeAllSizes(7, 11, +1)) // 7*n + 11*(n+1)
+ fmt.Println(makeAllSizes(9, 13, +2))
+ fmt.Println(makeAllSizes(11, 16, -1))
+ fmt.Println(makeAllSizes(17, 9, -2))
+
+ fmt.Println("}")
+}
diff --git a/test/method2.go b/test/method2.go
index e55aee42..a45a9431 100644
--- a/test/method2.go
+++ b/test/method2.go
@@ -35,3 +35,7 @@ var pv = &v
var _ = pv.val() // ERROR "pv.val undefined"
var _ = pv.val // ERROR "pv.val undefined"
+
+func (t *T) g() int { return t.a }
+
+var _ = (T).g() // ERROR "needs pointer receiver|undefined"
diff --git a/test/method6.go b/test/method6.go
new file mode 100644
index 00000000..20eccce4
--- /dev/null
+++ b/test/method6.go
@@ -0,0 +1,22 @@
+// errorcheck
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Verify that pointer method calls are caught during typechecking.
+// Reproducer extracted and adapted from method.go
+
+package foo
+
+type A struct {
+ B
+}
+type B int
+
+func (*B) g() {}
+
+var _ = func() {
+ var a A
+ A(a).g() // ERROR "cannot call pointer method on|cannot take the address of"
+}
diff --git a/test/method7.go b/test/method7.go
new file mode 100644
index 00000000..72c88b37
--- /dev/null
+++ b/test/method7.go
@@ -0,0 +1,56 @@
+// run
+
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test forms of method expressions T.m where T is
+// a literal type.
+
+package main
+
+var got, want string
+
+type I interface {
+ m()
+}
+
+type S struct {
+}
+
+func (S) m() { got += " m()" }
+func (S) m1(s string) { got += " m1(" + s + ")" }
+
+type T int
+
+func (T) m2() { got += " m2()" }
+
+func main() {
+ // method expressions with named receiver types
+ I.m(S{})
+ want += " m()"
+
+ S.m1(S{}, "a")
+ want += " m1(a)"
+
+ // method expressions with literal receiver types
+ f := interface{ m1(string) }.m1
+ f(S{}, "b")
+ want += " m1(b)"
+
+ interface{ m1(string) }.m1(S{}, "c")
+ want += " m1(c)"
+
+ x := S{}
+ interface{ m1(string) }.m1(x, "d")
+ want += " m1(d)"
+
+ // cannot link the call below - see #22444
+ // g := struct{ T }.m2
+ // g(struct{T}{})
+ // want += " m2()"
+
+ if got != want {
+ panic("got" + got + ", want" + want)
+ }
+}
diff --git a/test/nilptr3.go b/test/nilptr3.go
index 195c8ca0..9a96bb53 100644
--- a/test/nilptr3.go
+++ b/test/nilptr3.go
@@ -259,3 +259,10 @@ func f7() (*Struct, float64) {
func f8(t *[8]int) [8]int {
return *t // ERROR "removed nil check"
}
+
+func f9() []int {
+ x := new([1]int)
+ x[0] = 1 // ERROR "removed nil check"
+ y := x[:] // ERROR "removed nil check"
+ return y
+}
diff --git a/test/nosplit.go b/test/nosplit.go
index 989d8ccb..e6cecebd 100644
--- a/test/nosplit.go
+++ b/test/nosplit.go
@@ -115,15 +115,15 @@ main 132
main 136
# A nosplit leaf can use the whole 128-CallSize bytes available on entry.
-# (CallSize is 32 on ppc64)
+# (CallSize is 32 on ppc64, 8 on amd64 for frame pointer.)
main 96 nosplit
main 100 nosplit; REJECT ppc64 ppc64le
main 104 nosplit; REJECT ppc64 ppc64le
main 108 nosplit; REJECT ppc64 ppc64le
main 112 nosplit; REJECT ppc64 ppc64le
main 116 nosplit; REJECT ppc64 ppc64le
-main 120 nosplit; REJECT ppc64 ppc64le
-main 124 nosplit; REJECT ppc64 ppc64le
+main 120 nosplit; REJECT ppc64 ppc64le amd64
+main 124 nosplit; REJECT ppc64 ppc64le amd64
main 128 nosplit; REJECT
main 132 nosplit; REJECT
main 136 nosplit; REJECT
@@ -132,13 +132,14 @@ main 136 nosplit; REJECT
# 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.
# Because arm64 doesn't save LR in the leaf, it gets an extra 8 bytes.
-# ppc64 doesn't save LR in the leaf, but CallSize is 32, so it gets 24 fewer bytes than amd64.
+# ppc64 doesn't save LR in the leaf, but CallSize is 32, so it gets 24 bytes.
+# Because AMD64 uses frame pointer, it has 8 fewer bytes.
main 96 nosplit call f; f 0 nosplit
main 100 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le
main 104 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le
main 108 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le
-main 112 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le
-main 116 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le
+main 112 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64
+main 116 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64
main 120 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64
main 124 nosplit call f; f 0 nosplit; REJECT ppc64 ppc64le amd64 386
main 128 nosplit call f; f 0 nosplit; REJECT
@@ -148,11 +149,11 @@ 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.
-# RISC architectures differ in the same way as before.
+# Architectures differ in the same way as before.
main 96 nosplit call f; f 0 call f
main 100 nosplit call f; f 0 call f; REJECT ppc64 ppc64le
-main 104 nosplit call f; f 0 call f; REJECT ppc64 ppc64le
-main 108 nosplit call f; f 0 call f; REJECT ppc64 ppc64le
+main 104 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64
+main 108 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64
main 112 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64
main 116 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64
main 120 nosplit call f; f 0 call f; REJECT ppc64 ppc64le amd64 386
@@ -164,8 +165,8 @@ main 136 nosplit call f; f 0 call f; REJECT
# Indirect calls are assumed to be splitting functions.
main 96 nosplit callind
main 100 nosplit callind; REJECT ppc64 ppc64le
-main 104 nosplit callind; REJECT ppc64 ppc64le
-main 108 nosplit callind; REJECT ppc64 ppc64le
+main 104 nosplit callind; REJECT ppc64 ppc64le amd64
+main 108 nosplit callind; REJECT ppc64 ppc64le amd64
main 112 nosplit callind; REJECT ppc64 ppc64le amd64
main 116 nosplit callind; REJECT ppc64 ppc64le amd64
main 120 nosplit callind; REJECT ppc64 ppc64le amd64 386
@@ -198,18 +199,14 @@ func main() {
goarch = runtime.GOARCH
}
- // Frame pointer is on by default now.
- // golang.org/issue/18317.
- return
-
version, err := exec.Command("go", "tool", "compile", "-V").Output()
if err != nil {
bug()
fmt.Printf("running go tool compile -V: %v\n", err)
return
}
- if strings.Contains(string(version), "framepointer") {
- // Skip this test if GOEXPERIMENT=framepointer
+ if s := string(version); goarch == "amd64" && strings.Contains(s, "X:") && !strings.Contains(s, "framepointer") {
+ // Skip this test if framepointer is NOT enabled on AMD64
return
}
@@ -266,18 +263,18 @@ TestCases:
ptrSize := 4
switch goarch {
case "mips", "mipsle":
- fmt.Fprintf(&buf, "#define CALL JAL\n#define REGISTER (R0)\n")
+ fmt.Fprintf(&buf, "#define REGISTER (R0)\n")
case "mips64", "mips64le":
ptrSize = 8
- fmt.Fprintf(&buf, "#define CALL JAL\n#define REGISTER (R0)\n")
+ fmt.Fprintf(&buf, "#define REGISTER (R0)\n")
case "ppc64", "ppc64le":
ptrSize = 8
- fmt.Fprintf(&buf, "#define CALL BL\n#define REGISTER (CTR)\n")
+ fmt.Fprintf(&buf, "#define REGISTER (CTR)\n")
case "arm":
- fmt.Fprintf(&buf, "#define CALL BL\n#define REGISTER (R0)\n")
+ fmt.Fprintf(&buf, "#define REGISTER (R0)\n")
case "arm64":
ptrSize = 8
- fmt.Fprintf(&buf, "#define CALL BL\n#define REGISTER (R0)\n")
+ fmt.Fprintf(&buf, "#define REGISTER (R0)\n")
case "amd64":
ptrSize = 8
fmt.Fprintf(&buf, "#define REGISTER AX\n")
@@ -307,7 +304,7 @@ TestCases:
name := m[1]
size, _ := strconv.Atoi(m[2])
- // The limit was originally 128 but is now 592.
+ // The limit was originally 128 but is now 752 (880-128).
// Instead of rewriting the test cases above, adjust
// the first stack frame to use up the extra bytes.
if i == 0 {
diff --git a/test/notinheap3.go b/test/notinheap3.go
new file mode 100644
index 00000000..d48c2a0c
--- /dev/null
+++ b/test/notinheap3.go
@@ -0,0 +1,60 @@
+// errorcheck -+ -0 -l -d=wb
+
+// Copyright 2016 The Go 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 write barrier elimination for notinheap.
+
+package p
+
+type t1 struct {
+ x *nih
+ s []nih
+ y [1024]byte // Prevent write decomposition
+}
+
+type t2 struct {
+ x *ih
+ s []ih
+ y [1024]byte
+}
+
+//go:notinheap
+type nih struct {
+ x uintptr
+}
+
+type ih struct { // In-heap type
+ x uintptr
+}
+
+var (
+ v1 t1
+ v2 t2
+
+ v1s []t1
+ v2s []t2
+)
+
+func f() {
+ // Test direct writes
+ v1.x = nil // no barrier
+ v2.x = nil // ERROR "write barrier"
+ v1.s = []nih(nil) // no barrier
+ v2.s = []ih(nil) // ERROR "write barrier"
+}
+
+func g() {
+ // Test aggregate writes
+ v1 = t1{x: nil} // no barrier
+ v2 = t2{x: nil} // ERROR "write barrier"
+}
+
+func h() {
+ // Test copies and appends.
+ copy(v1s, v1s[1:]) // no barrier
+ copy(v2s, v2s[1:]) // ERROR "write barrier"
+ _ = append(v1s, v1s...) // no barrier
+ _ = append(v2s, v2s...) // ERROR "write barrier"
+}
diff --git a/test/nowritebarrier.go b/test/nowritebarrier.go
index 23dce753..64666fa5 100644
--- a/test/nowritebarrier.go
+++ b/test/nowritebarrier.go
@@ -76,3 +76,18 @@ func d3() {
func d4() {
d2()
}
+
+//go:noinline
+func systemstack(func()) {}
+
+//go:nowritebarrierrec
+func e1() {
+ systemstack(e2)
+ systemstack(func() {
+ x.f = y // ERROR "write barrier prohibited by caller"
+ })
+}
+
+func e2() {
+ x.f = y // ERROR "write barrier prohibited by caller"
+}
diff --git a/test/print.go b/test/print.go
index 466e19f1..b7f3db0a 100644
--- a/test/print.go
+++ b/test/print.go
@@ -19,6 +19,11 @@ func main() {
println(([]int)(nil)) // printslice
println(int64(-7)) // printint
println(uint64(7)) // printuint
+ println(uint32(7)) // printuint
+ println(uint16(7)) // printuint
+ println(uint8(7)) // printuint
+ println(uint(7)) // printuint
+ println(uintptr(7)) // printuint
println(8.0) // printfloat
println(complex(9.0, 10.0)) // printcomplex
println(true) // printbool
@@ -28,11 +33,18 @@ func main() {
// test goprintf
defer println((interface{})(nil))
- defer println((interface{f()})(nil))
+ defer println((interface {
+ f()
+ })(nil))
defer println((map[int]int)(nil))
defer println(([]int)(nil))
defer println(int64(-11))
defer println(uint64(12))
+ defer println(uint32(12))
+ defer println(uint16(12))
+ defer println(uint8(12))
+ defer println(uint(12))
+ defer println(uintptr(12))
defer println(13.0)
defer println(complex(14.0, 15.0))
defer println(true)
diff --git a/test/print.out b/test/print.out
index 266fe5d6..85376af0 100644
--- a/test/print.out
+++ b/test/print.out
@@ -4,6 +4,11 @@
[0/0]0x0
-7
7
+7
+7
+7
+7
+7
+8.000000e+000
(+9.000000e+000+1.000000e+001i)
true
@@ -17,6 +22,11 @@ true
(+1.400000e+001+1.500000e+001i)
+1.300000e+001
12
+12
+12
+12
+12
+12
-11
[0/0]0x0
0x0
diff --git a/test/range.go b/test/range.go
index afdac57f..3da7d170 100644
--- a/test/range.go
+++ b/test/range.go
@@ -23,12 +23,57 @@ func seq(lo, hi int) chan int {
return c
}
+const alphabet = "abcdefghijklmnopqrstuvwxyz"
+
+func testblankvars() {
+ n := 0
+ for range alphabet {
+ n++
+ }
+ if n != 26 {
+ println("for range: wrong count", n, "want 26")
+ panic("fail")
+ }
+ n = 0
+ for _ = range alphabet {
+ n++
+ }
+ if n != 26 {
+ println("for _ = range: wrong count", n, "want 26")
+ panic("fail")
+ }
+ n = 0
+ for _, _ = range alphabet {
+ n++
+ }
+ if n != 26 {
+ println("for _, _ = range: wrong count", n, "want 26")
+ panic("fail")
+ }
+ s := 0
+ for i, _ := range alphabet {
+ s += i
+ }
+ if s != 325 {
+ println("for i, _ := range: wrong sum", s, "want 325")
+ panic("fail")
+ }
+ r := rune(0)
+ for _, v := range alphabet {
+ r += v
+ }
+ if r != 2847 {
+ println("for _, v := range: wrong sum", r, "want 2847")
+ panic("fail")
+ }
+}
+
func testchan() {
s := ""
for i := range seq('a', 'z') {
s += string(i)
}
- if s != "abcdefghijklmnopqrstuvwxyz" {
+ if s != alphabet {
println("Wanted lowercase alphabet; got", s)
panic("fail")
}
@@ -38,6 +83,7 @@ func testchan() {
}
if n != 26 {
println("testchan wrong count", n, "want 26")
+ panic("fail")
}
}
@@ -426,6 +472,7 @@ func testcalls() {
}
func main() {
+ testblankvars()
testchan()
testarray()
testarray1()
diff --git a/test/recover4.go b/test/recover4.go
index da5117cc..67ed970e 100644
--- a/test/recover4.go
+++ b/test/recover4.go
@@ -68,6 +68,6 @@ func main() {
log.Fatal("no error from memcopy across memory hole")
}
if n != 8*size-5 {
- log.Fatal("memcopy returned %d, want %d", n, 8*size-5)
+ log.Fatalf("memcopy returned %d, want %d", n, 8*size-5)
}
}
diff --git a/test/rename1.go b/test/rename1.go
index a71e5b2e..568aa13d 100644
--- a/test/rename1.go
+++ b/test/rename1.go
@@ -10,10 +10,10 @@
package main
func main() {
- var n byte // ERROR "not a type|expected type"
+ var n byte // ERROR "not a type|expected type"
var y = float32(0) // ERROR "cannot call|expected function"
const (
- a = 1 + iota // ERROR "string|incompatible types" "convert iota"
+ a = 1 + iota // ERROR "invalid operation|incompatible types" "cannot convert iota"
)
}
diff --git a/test/run.go b/test/run.go
index 2fa20674..22ec7576 100644
--- a/test/run.go
+++ b/test/run.go
@@ -417,6 +417,14 @@ func (ctxt *context) match(name string) bool {
func init() { checkShouldTest() }
+// goGcflags returns the -gcflags argument to use with go build / go run.
+// This must match the flags used for building the standard libary,
+// or else the commands will rebuild any needed packages (like runtime)
+// over and over.
+func goGcflags() string {
+ return "-gcflags=" + os.Getenv("GO_GCFLAGS")
+}
+
// run runs a test.
func (t *test) run() {
start := time.Now()
@@ -701,7 +709,7 @@ func (t *test) run() {
}
case "build":
- _, err := runcmd("go", "build", "-o", "a.exe", long)
+ _, err := runcmd("go", "build", goGcflags(), "-o", "a.exe", long)
if err != nil {
t.err = err
}
@@ -728,6 +736,9 @@ func (t *test) run() {
}
var objs []string
cmd := []string{"go", "tool", "compile", "-e", "-D", ".", "-I", ".", "-o", "go.o"}
+ if len(asms) > 0 {
+ cmd = append(cmd, "-asmhdr", "go_asm.h")
+ }
for _, file := range gos {
cmd = append(cmd, filepath.Join(longdir, file.Name()))
}
@@ -766,7 +777,7 @@ func (t *test) run() {
case "buildrun": // build binary, then run binary, instead of go run. Useful for timeout tests where failure mode is infinite loop.
// TODO: not supported on NaCl
useTmp = true
- cmd := []string{"go", "build", "-o", "a.exe"}
+ cmd := []string{"go", "build", goGcflags(), "-o", "a.exe"}
if *linkshared {
cmd = append(cmd, "-linkshared")
}
@@ -791,13 +802,38 @@ func (t *test) run() {
case "run":
useTmp = false
- cmd := []string{"go", "run"}
- if *linkshared {
- cmd = append(cmd, "-linkshared")
+ var out []byte
+ var err error
+ if len(flags)+len(args) == 0 && goGcflags() == "" && !*linkshared {
+ // If we're not using special go command flags,
+ // skip all the go command machinery.
+ // This avoids any time the go command would
+ // spend checking whether, for example, the installed
+ // package runtime is up to date.
+ // Because we run lots of trivial test programs,
+ // the time adds up.
+ pkg := filepath.Join(t.tempDir, "pkg.a")
+ if _, err := runcmd("go", "tool", "compile", "-o", pkg, t.goFileName()); err != nil {
+ t.err = err
+ return
+ }
+ exe := filepath.Join(t.tempDir, "test.exe")
+ cmd := []string{"go", "tool", "link", "-s", "-w"}
+ cmd = append(cmd, "-o", exe, pkg)
+ if _, err := runcmd(cmd...); err != nil {
+ t.err = err
+ return
+ }
+ out, err = runcmd(append([]string{exe}, args...)...)
+ } else {
+ cmd := []string{"go", "run", goGcflags()}
+ if *linkshared {
+ cmd = append(cmd, "-linkshared")
+ }
+ cmd = append(cmd, flags...)
+ cmd = append(cmd, t.goFileName())
+ out, err = runcmd(append(cmd, args...)...)
}
- cmd = append(cmd, flags...)
- cmd = append(cmd, t.goFileName())
- out, err := runcmd(append(cmd, args...)...)
if err != nil {
t.err = err
return
@@ -812,7 +848,7 @@ func (t *test) run() {
<-rungatec
}()
useTmp = false
- cmd := []string{"go", "run"}
+ cmd := []string{"go", "run", goGcflags()}
if *linkshared {
cmd = append(cmd, "-linkshared")
}
@@ -827,7 +863,7 @@ func (t *test) run() {
t.err = fmt.Errorf("write tempfile:%s", err)
return
}
- cmd = []string{"go", "run"}
+ cmd = []string{"go", "run", goGcflags()}
if *linkshared {
cmd = append(cmd, "-linkshared")
}
@@ -843,7 +879,7 @@ func (t *test) run() {
case "errorcheckoutput":
useTmp = false
- cmd := []string{"go", "run"}
+ cmd := []string{"go", "run", goGcflags()}
if *linkshared {
cmd = append(cmd, "-linkshared")
}
diff --git a/test/shift1.go b/test/shift1.go
index c81ee515..01ecbed5 100644
--- a/test/shift1.go
+++ b/test/shift1.go
@@ -152,8 +152,7 @@ func _() {
var a []int
_ = a[1<<s]
_ = a[1.]
- // For now, the spec disallows these. We may revisit past Go 1.1.
- _ = a[1.<<s] // ERROR "integer|shift of type float64"
+ _ = a[1.<<s]
_ = a[1.1<<s] // ERROR "integer|shift of type float64"
_ = make([]int, 1)