aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/fixedbugs/issue12347.go16
-rw-r--r--test/goto.go72
-rw-r--r--test/label.go7
-rw-r--r--test/label1.go32
-rw-r--r--test/live.go1
-rw-r--r--test/live2.go1
-rw-r--r--test/nilcheck.go98
-rw-r--r--test/nilptr3.go2
-rw-r--r--test/nilptr3_ssa.go209
-rw-r--r--test/nosplit.go5
-rw-r--r--test/opt_branchlikely.go85
-rw-r--r--test/phiopt.go43
-rw-r--r--test/prove.go207
-rw-r--r--test/run.go15
-rw-r--r--test/sliceopt.go1
15 files changed, 699 insertions, 95 deletions
diff --git a/test/fixedbugs/issue12347.go b/test/fixedbugs/issue12347.go
new file mode 100644
index 0000000000..4bbe09c3e8
--- /dev/null
+++ b/test/fixedbugs/issue12347.go
@@ -0,0 +1,16 @@
+// compile
+
+// Copyright 2015 The Go 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_ssa(x int, p *int) {
+ if false {
+ y := x + 5
+ for {
+ *p = y
+ }
+ }
+}
diff --git a/test/goto.go b/test/goto.go
index ca477b3d0c..2daaa950af 100644
--- a/test/goto.go
+++ b/test/goto.go
@@ -40,7 +40,7 @@ L:
// goto across declaration not okay
func _() {
goto L // ERROR "goto L jumps over declaration of x at LINE+1|goto jumps over declaration"
- x := 1 // GCCGO_ERROR "defined here"
+ x := 1 // GCCGO_ERROR "defined here"
_ = x
L:
}
@@ -62,7 +62,7 @@ func _() {
x := 1
_ = x
}
- x := 1 // GCCGO_ERROR "defined here"
+ x := 1 // GCCGO_ERROR "defined here"
_ = x
L:
}
@@ -78,7 +78,7 @@ L:
// error shows first offending variable
func _() {
goto L // ERROR "goto L jumps over declaration of x at LINE+1|goto jumps over declaration"
- x := 1 // GCCGO_ERROR "defined here"
+ x := 1 // GCCGO_ERROR "defined here"
_ = x
y := 1
_ = y
@@ -88,7 +88,7 @@ L:
// goto not okay even if code path is dead
func _() {
goto L // ERROR "goto L jumps over declaration of x at LINE+1|goto jumps over declaration"
- x := 1 // GCCGO_ERROR "defined here"
+ x := 1 // GCCGO_ERROR "defined here"
_ = x
y := 1
_ = y
@@ -115,14 +115,14 @@ L:
// goto into inner block not okay
func _() {
goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
- { // GCCGO_ERROR "block starts here"
+ { // GCCGO_ERROR "block starts here"
L:
}
}
// goto backward into inner block still not okay
func _() {
- { // GCCGO_ERROR "block starts here"
+ { // GCCGO_ERROR "block starts here"
L:
}
goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
@@ -133,7 +133,7 @@ func _() {
goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
{
{
- { // GCCGO_ERROR "block starts here"
+ { // GCCGO_ERROR "block starts here"
L:
}
}
@@ -145,7 +145,7 @@ func _() {
goto L // ERROR "goto L jumps into block starting at LINE+3|goto jumps into block"
x := 1
_ = x
- { // GCCGO_ERROR "block starts here"
+ { // GCCGO_ERROR "block starts here"
L:
}
}
@@ -179,15 +179,15 @@ L:
}
func _() {
- goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
- if true { // GCCGO_ERROR "block starts here"
+ goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
+ if true { // GCCGO_ERROR "block starts here"
L:
}
}
func _() {
- goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
- if true { // GCCGO_ERROR "block starts here"
+ goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
+ if true { // GCCGO_ERROR "block starts here"
L:
} else {
}
@@ -196,13 +196,13 @@ func _() {
func _() {
goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
if true {
- } else { // GCCGO_ERROR "block starts here"
+ } else { // GCCGO_ERROR "block starts here"
L:
}
}
func _() {
- if false { // GCCGO_ERROR "block starts here"
+ if false { // GCCGO_ERROR "block starts here"
L:
} else {
goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
@@ -212,7 +212,7 @@ func _() {
func _() {
if true {
goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
- } else { // GCCGO_ERROR "block starts here"
+ } else { // GCCGO_ERROR "block starts here"
L:
}
}
@@ -220,7 +220,7 @@ func _() {
func _() {
if true {
goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
- } else if false { // GCCGO_ERROR "block starts here"
+ } else if false { // GCCGO_ERROR "block starts here"
L:
}
}
@@ -228,7 +228,7 @@ func _() {
func _() {
if true {
goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
- } else if false { // GCCGO_ERROR "block starts here"
+ } else if false { // GCCGO_ERROR "block starts here"
L:
} else {
}
@@ -243,7 +243,7 @@ func _() {
if true {
goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
} else if false {
- } else { // GCCGO_ERROR "block starts here"
+ } else { // GCCGO_ERROR "block starts here"
L:
}
}
@@ -287,14 +287,14 @@ func _() {
}
func _() {
- for { // GCCGO_ERROR "block starts here"
+ for { // GCCGO_ERROR "block starts here"
L:
}
goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
}
func _() {
- for { // GCCGO_ERROR "block starts here"
+ for { // GCCGO_ERROR "block starts here"
goto L
L1:
}
@@ -303,42 +303,42 @@ L:
}
func _() {
- for i < n { // GCCGO_ERROR "block starts here"
+ for i < n { // GCCGO_ERROR "block starts here"
L:
}
goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
}
func _() {
- for i = 0; i < n; i++ { // GCCGO_ERROR "block starts here"
+ for i = 0; i < n; i++ { // GCCGO_ERROR "block starts here"
L:
}
goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
}
func _() {
- for i = range x { // GCCGO_ERROR "block starts here"
+ for i = range x { // GCCGO_ERROR "block starts here"
L:
}
goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
}
func _() {
- for i = range c { // GCCGO_ERROR "block starts here"
+ for i = range c { // GCCGO_ERROR "block starts here"
L:
}
goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
}
func _() {
- for i = range m { // GCCGO_ERROR "block starts here"
+ for i = range m { // GCCGO_ERROR "block starts here"
L:
}
goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
}
func _() {
- for i = range s { // GCCGO_ERROR "block starts here"
+ for i = range s { // GCCGO_ERROR "block starts here"
L:
}
goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
@@ -398,7 +398,7 @@ func _() {
goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
switch i {
case 0:
- L: // GCCGO_ERROR "block starts here"
+ L: // GCCGO_ERROR "block starts here"
}
}
@@ -406,7 +406,7 @@ func _() {
goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
switch i {
case 0:
- L: // GCCGO_ERROR "block starts here"
+ L: // GCCGO_ERROR "block starts here"
;
default:
}
@@ -417,7 +417,7 @@ func _() {
switch i {
case 0:
default:
- L: // GCCGO_ERROR "block starts here"
+ L: // GCCGO_ERROR "block starts here"
}
}
@@ -426,14 +426,14 @@ func _() {
default:
goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
case 0:
- L: // GCCGO_ERROR "block starts here"
+ L: // GCCGO_ERROR "block starts here"
}
}
func _() {
switch i {
case 0:
- L: // GCCGO_ERROR "block starts here"
+ L: // GCCGO_ERROR "block starts here"
;
default:
goto L // ERROR "goto L jumps into block starting at LINE-4|goto jumps into block"
@@ -495,7 +495,7 @@ func _() {
goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
select {
case c <- 1:
- L: // GCCGO_ERROR "block starts here"
+ L: // GCCGO_ERROR "block starts here"
}
}
@@ -503,7 +503,7 @@ func _() {
goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
select {
case c <- 1:
- L: // GCCGO_ERROR "block starts here"
+ L: // GCCGO_ERROR "block starts here"
;
default:
}
@@ -514,7 +514,7 @@ func _() {
select {
case <-c:
default:
- L: // GCCGO_ERROR "block starts here"
+ L: // GCCGO_ERROR "block starts here"
}
}
@@ -523,14 +523,14 @@ func _() {
default:
goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
case <-c:
- L: // GCCGO_ERROR "block starts here"
+ L: // GCCGO_ERROR "block starts here"
}
}
func _() {
select {
case <-c:
- L: // GCCGO_ERROR "block starts here"
+ L: // GCCGO_ERROR "block starts here"
;
default:
goto L // ERROR "goto L jumps into block starting at LINE-4|goto jumps into block"
diff --git a/test/label.go b/test/label.go
index b30c27ec44..c3c0c27edd 100644
--- a/test/label.go
+++ b/test/label.go
@@ -17,8 +17,7 @@ L1: // ERROR "label .*L1.* defined and not used"
for {
}
L2: // ERROR "label .*L2.* defined and not used"
- select {
- }
+ select {}
L3: // ERROR "label .*L3.* defined and not used"
switch {
}
@@ -59,4 +58,8 @@ L10:
default:
break L10
}
+
+ goto L10
+
+ goto go2 // ERROR "label go2 not defined"
}
diff --git a/test/label1.go b/test/label1.go
index f923a18820..937b5cb900 100644
--- a/test/label1.go
+++ b/test/label1.go
@@ -4,7 +4,6 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-
// Verify that erroneous labels are caught by the compiler.
// This set is caught by pass 2. That's why this file is label1.go.
// Does not compile.
@@ -32,11 +31,17 @@ L2:
break L2
}
if x == 1 {
- continue L2 // ERROR "invalid continue label .*L2"
+ continue L2 // ERROR "invalid continue label .*L2|continue is not in a loop"
}
goto L2
}
+ for {
+ if x == 1 {
+ continue L2 // ERROR "invalid continue label .*L2"
+ }
+ }
+
L3:
switch {
case x > 10:
@@ -44,7 +49,7 @@ L3:
break L3
}
if x == 12 {
- continue L3 // ERROR "invalid continue label .*L3"
+ continue L3 // ERROR "invalid continue label .*L3|continue is not in a loop"
}
goto L3
}
@@ -55,7 +60,7 @@ L4:
break L4 // ERROR "invalid break label .*L4"
}
if x == 14 {
- continue L4 // ERROR "invalid continue label .*L4"
+ continue L4 // ERROR "invalid continue label .*L4|continue is not in a loop"
}
if x == 15 {
goto L4
@@ -68,7 +73,7 @@ L5:
break L5 // ERROR "invalid break label .*L5"
}
if x == 17 {
- continue L5 // ERROR "invalid continue label .*L5"
+ continue L5 // ERROR "invalid continue label .*L5|continue is not in a loop"
}
if x == 18 {
goto L5
@@ -85,4 +90,21 @@ L5:
goto L1
}
}
+
+ continue // ERROR "continue is not in a loop"
+ for {
+ continue on // ERROR "continue label not defined: on"
+ }
+
+ break // ERROR "break is not in a loop"
+ for {
+ break dance // ERROR "break label not defined: dance"
+ }
+
+ for {
+ switch x {
+ case 1:
+ continue
+ }
+ }
}
diff --git a/test/live.go b/test/live.go
index ae982f4957..c54f091d1b 100644
--- a/test/live.go
+++ b/test/live.go
@@ -1,3 +1,4 @@
+// +build !amd64
// errorcheck -0 -l -live -wb=0
// Copyright 2014 The Go Authors. All rights reserved.
diff --git a/test/live2.go b/test/live2.go
index 7474756157..430f9feb7e 100644
--- a/test/live2.go
+++ b/test/live2.go
@@ -1,3 +1,4 @@
+// +build !amd64
// errorcheck -0 -live -wb=0
// Copyright 2014 The Go Authors. All rights reserved.
diff --git a/test/nilcheck.go b/test/nilcheck.go
index 99c3c5fdb6..ab28b33d41 100644
--- a/test/nilcheck.go
+++ b/test/nilcheck.go
@@ -17,7 +17,7 @@ type Struct struct {
type BigStruct struct {
X int
Y float64
- A [1<<20]int
+ A [1 << 20]int
Z string
}
@@ -29,86 +29,86 @@ type Empty1 struct {
}
var (
- intp *int
- arrayp *[10]int
- array0p *[0]int
- bigarrayp *[1<<26]int
- structp *Struct
+ intp *int
+ arrayp *[10]int
+ array0p *[0]int
+ bigarrayp *[1 << 26]int
+ structp *Struct
bigstructp *BigStruct
- emptyp *Empty
- empty1p *Empty1
+ emptyp *Empty
+ empty1p *Empty1
)
func f1() {
- _ = *intp // ERROR "nil check"
- _ = *arrayp // ERROR "nil check"
+ _ = *intp // ERROR "nil check"
+ _ = *arrayp // ERROR "nil check"
_ = *array0p // ERROR "nil check"
_ = *array0p // ERROR "nil check"
- _ = *intp // ERROR "nil check"
- _ = *arrayp // ERROR "nil check"
+ _ = *intp // ERROR "nil check"
+ _ = *arrayp // ERROR "nil check"
_ = *structp // ERROR "nil check"
- _ = *emptyp // ERROR "nil check"
- _ = *arrayp // ERROR "nil check"
+ _ = *emptyp // ERROR "nil check"
+ _ = *arrayp // ERROR "nil check"
}
func f2() {
var (
- intp *int
- arrayp *[10]int
- array0p *[0]int
- bigarrayp *[1<<20]int
- structp *Struct
+ intp *int
+ arrayp *[10]int
+ array0p *[0]int
+ bigarrayp *[1 << 20]int
+ structp *Struct
bigstructp *BigStruct
- emptyp *Empty
- empty1p *Empty1
+ emptyp *Empty
+ empty1p *Empty1
)
- _ = *intp // ERROR "nil check"
- _ = *arrayp // ERROR "nil check"
- _ = *array0p // ERROR "nil check"
- _ = *array0p // ERROR "nil check"
- _ = *intp // ERROR "nil check"
- _ = *arrayp // ERROR "nil check"
- _ = *structp // ERROR "nil check"
- _ = *emptyp // ERROR "nil check"
- _ = *arrayp // ERROR "nil check"
- _ = *bigarrayp // ERROR "nil check"
+ _ = *intp // ERROR "nil check"
+ _ = *arrayp // ERROR "nil check"
+ _ = *array0p // ERROR "nil check"
+ _ = *array0p // ERROR "nil check"
+ _ = *intp // ERROR "nil check"
+ _ = *arrayp // ERROR "nil check"
+ _ = *structp // ERROR "nil check"
+ _ = *emptyp // ERROR "nil check"
+ _ = *arrayp // ERROR "nil check"
+ _ = *bigarrayp // ERROR "nil check"
_ = *bigstructp // ERROR "nil check"
- _ = *empty1p // ERROR "nil check"
+ _ = *empty1p // ERROR "nil check"
}
func fx10k() *[10000]int
-var b bool
+var b bool
func f3(x *[10000]int) {
// Using a huge type and huge offsets so the compiler
// does not expect the memory hardware to fault.
_ = x[9999] // ERROR "nil check"
-
+
for {
if x[9999] != 0 { // ERROR "nil check"
break
}
}
-
- x = fx10k()
+
+ x = fx10k()
_ = x[9999] // ERROR "nil check"
if b {
_ = x[9999] // ERROR "nil check"
} else {
_ = x[9999] // ERROR "nil check"
- }
+ }
_ = x[9999] // ERROR "nil check"
- x = fx10k()
+ x = fx10k()
if b {
_ = x[9999] // ERROR "nil check"
} else {
_ = x[9999] // ERROR "nil check"
- }
+ }
_ = x[9999] // ERROR "nil check"
-
+
fx10k()
// This one is a bit redundant, if we figured out that
// x wasn't going to change across the function call.
@@ -138,7 +138,7 @@ func f3b() {
_ = &x[9] // ERROR "nil check"
}
-func fx10() *[10]int
+func fx10() *[10]int
func f4(x *[10]int) {
// Most of these have no checks because a real memory reference follows,
@@ -146,33 +146,33 @@ func f4(x *[10]int) {
// in the first unmapped page of memory.
_ = x[9] // ERROR "nil check"
-
+
for {
if x[9] != 0 { // ERROR "nil check"
break
}
}
-
- x = fx10()
+
+ x = fx10()
_ = x[9] // ERROR "nil check"
if b {
_ = x[9] // ERROR "nil check"
} else {
_ = x[9] // ERROR "nil check"
- }
+ }
_ = x[9] // ERROR "nil check"
- x = fx10()
+ x = fx10()
if b {
_ = x[9] // ERROR "nil check"
} else {
_ = &x[9] // ERROR "nil check"
- }
+ }
_ = x[9] // ERROR "nil check"
-
+
fx10()
_ = x[9] // ERROR "nil check"
-
+
x = fx10()
y := fx10()
_ = &x[9] // ERROR "nil check"
diff --git a/test/nilptr3.go b/test/nilptr3.go
index 6c8aab32cb..1ba774d839 100644
--- a/test/nilptr3.go
+++ b/test/nilptr3.go
@@ -2,7 +2,7 @@
// Fails on ppc64x because of incomplete optimization.
// See issues 9058.
// Same reason for mips64x.
-// +build !ppc64,!ppc64le,!mips64,!mips64le
+// +build !ppc64,!ppc64le,!mips64,!mips64le,!amd64
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
diff --git a/test/nilptr3_ssa.go b/test/nilptr3_ssa.go
new file mode 100644
index 0000000000..ba60a64602
--- /dev/null
+++ b/test/nilptr3_ssa.go
@@ -0,0 +1,209 @@
+// errorcheck -0 -d=nil
+// Fails on ppc64x because of incomplete optimization.
+// See issues 9058.
+// +build !ppc64,!ppc64le,amd64
+
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test that nil checks are removed.
+// Optimization is enabled.
+
+package p
+
+type Struct struct {
+ X int
+ Y float64
+}
+
+type BigStruct struct {
+ X int
+ Y float64
+ A [1 << 20]int
+ Z string
+}
+
+type Empty struct {
+}
+
+type Empty1 struct {
+ Empty
+}
+
+var (
+ intp *int
+ arrayp *[10]int
+ array0p *[0]int
+ bigarrayp *[1 << 26]int
+ structp *Struct
+ bigstructp *BigStruct
+ emptyp *Empty
+ empty1p *Empty1
+)
+
+func f1() {
+ _ = *intp // ERROR "generated nil check"
+
+ // This one should be removed but the block copy needs
+ // to be turned into its own pseudo-op in order to see
+ // the indirect.
+ _ = *arrayp // ERROR "generated nil check"
+
+ // 0-byte indirect doesn't suffice.
+ // we don't registerize globals, so there are no removed.* nil checks.
+ _ = *array0p // ERROR "generated nil check"
+ _ = *array0p // ERROR "removed nil check"
+
+ _ = *intp // ERROR "removed nil check"
+ _ = *arrayp // ERROR "removed nil check"
+ _ = *structp // ERROR "generated nil check"
+ _ = *emptyp // ERROR "generated nil check"
+ _ = *arrayp // ERROR "removed nil check"
+}
+
+func f2() {
+ var (
+ intp *int
+ arrayp *[10]int
+ array0p *[0]int
+ bigarrayp *[1 << 20]int
+ structp *Struct
+ bigstructp *BigStruct
+ emptyp *Empty
+ empty1p *Empty1
+ )
+
+ _ = *intp // ERROR "generated nil check"
+ _ = *arrayp // ERROR "generated nil check"
+ _ = *array0p // ERROR "generated nil check"
+ _ = *array0p // ERROR "removed.* nil check"
+ _ = *intp // ERROR "removed.* nil check"
+ _ = *arrayp // ERROR "removed.* nil check"
+ _ = *structp // ERROR "generated nil check"
+ _ = *emptyp // ERROR "generated nil check"
+ _ = *arrayp // ERROR "removed.* nil check"
+ _ = *bigarrayp // ERROR "generated nil check" ARM removed nil check before indirect!!
+ _ = *bigstructp // ERROR "generated nil check"
+ _ = *empty1p // ERROR "generated nil check"
+}
+
+func fx10k() *[10000]int
+
+var b bool
+
+func f3(x *[10000]int) {
+ // Using a huge type and huge offsets so the compiler
+ // does not expect the memory hardware to fault.
+ _ = x[9999] // ERROR "generated nil check"
+
+ for {
+ if x[9999] != 0 { // ERROR "removed nil check"
+ break
+ }
+ }
+
+ x = fx10k()
+ _ = x[9999] // ERROR "generated nil check"
+ if b {
+ _ = x[9999] // ERROR "removed.* nil check"
+ } else {
+ _ = x[9999] // ERROR "removed.* nil check"
+ }
+ _ = x[9999] // ERROR "removed nil check"
+
+ x = fx10k()
+ if b {
+ _ = x[9999] // ERROR "generated nil check"
+ } else {
+ _ = x[9999] // ERROR "generated nil check"
+ }
+ _ = x[9999] // ERROR "generated nil check"
+
+ fx10k()
+ // This one is a bit redundant, if we figured out that
+ // x wasn't going to change across the function call.
+ // But it's a little complex to do and in practice doesn't
+ // matter enough.
+ _ = x[9999] // ERROR "removed nil check"
+}
+
+func f3a() {
+ x := fx10k()
+ y := fx10k()
+ z := fx10k()
+ _ = &x[9] // ERROR "generated nil check"
+ y = z
+ _ = &x[9] // ERROR "removed.* nil check"
+ x = y
+ _ = &x[9] // ERROR "generated nil check"
+}
+
+func f3b() {
+ x := fx10k()
+ y := fx10k()
+ _ = &x[9] // ERROR "generated nil check"
+ y = x
+ _ = &x[9] // ERROR "removed.* nil check"
+ x = y
+ _ = &x[9] // ERROR "removed.* nil check"
+}
+
+func fx10() *[10]int
+
+func f4(x *[10]int) {
+ // Most of these have no checks because a real memory reference follows,
+ // and the offset is small enough that if x is nil, the address will still be
+ // in the first unmapped page of memory.
+
+ _ = x[9] // ERROR "removed nil check"
+
+ for {
+ if x[9] != 0 { // ERROR "removed nil check"
+ break
+ }
+ }
+
+ x = fx10()
+ _ = x[9] // ERROR "generated nil check" // bug would like to remove before indirect
+ if b {
+ _ = x[9] // ERROR "removed nil check"
+ } else {
+ _ = x[9] // ERROR "removed nil check"
+ }
+ _ = x[9] // ERROR "removed nil check"
+
+ x = fx10()
+ if b {
+ _ = x[9] // ERROR "generated nil check" // bug would like to remove before indirect
+ } else {
+ _ = &x[9] // ERROR "generated nil check"
+ }
+ _ = x[9] // ERROR "generated nil check" // bug would like to remove before indirect
+
+ fx10()
+ _ = x[9] // ERROR "removed nil check"
+
+ x = fx10()
+ y := fx10()
+ _ = &x[9] // ERROR "generated nil check"
+ y = x
+ _ = &x[9] // ERROR "removed[a-z ]* nil check"
+ x = y
+ _ = &x[9] // ERROR "removed[a-z ]* nil check"
+}
+
+func f5(p *float32, q *float64, r *float32, s *float64) float64 {
+ x := float64(*p) // ERROR "removed nil check"
+ y := *q // ERROR "removed nil check"
+ *r = 7 // ERROR "removed nil check"
+ *s = 9 // ERROR "removed nil check"
+ return x + y
+}
+
+type T [29]byte
+
+func f6(p, q *T) {
+ x := *p // ERROR "removed nil check"
+ *q = x // ERROR "removed nil check"
+}
diff --git a/test/nosplit.go b/test/nosplit.go
index 3c4ae1079d..082fc3b0e6 100644
--- a/test/nosplit.go
+++ b/test/nosplit.go
@@ -302,9 +302,10 @@ TestCases:
// Instead of rewriting the test cases above, adjust
// the first stack frame to use up the extra bytes.
if i == 0 {
- size += 592 - 128
+ size += (720 - 128) - 128
// Noopt builds have a larger stackguard.
- // See ../cmd/dist/buildruntime.go:stackGuardMultiplier
+ // See ../src/cmd/dist/buildruntime.go:stackGuardMultiplier
+ // This increase is included in obj.StackGuard
for _, s := range strings.Split(os.Getenv("GO_GCFLAGS"), " ") {
if s == "-N" {
size += 720
diff --git a/test/opt_branchlikely.go b/test/opt_branchlikely.go
new file mode 100644
index 0000000000..99e914654f
--- /dev/null
+++ b/test/opt_branchlikely.go
@@ -0,0 +1,85 @@
+// +build amd64
+// errorcheck -0 -d=ssa/likelyadjust/debug=1
+
+// 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 that branches have some prediction properties.
+package foo
+
+func f(x, y, z int) int {
+ a := 0
+ for i := 0; i < x; i++ { // ERROR "Branch prediction rule stay in loop"
+ for j := 0; j < y; j++ { // ERROR "Branch prediction rule stay in loop"
+ a += j
+ }
+ for k := 0; k < z; k++ { // ERROR "Branch prediction rule stay in loop"
+ a -= x + y + z
+ }
+ }
+ return a
+}
+
+func g(x, y, z int) int {
+ a := 0
+ if y == 0 { // ERROR "Branch prediction rule default < call"
+ y = g(y, z, x)
+ } else {
+ y++
+ }
+ if y == x { // ERROR "Branch prediction rule default < call"
+ y = g(y, z, x)
+ } else {
+ }
+ if y == 2 { // ERROR "Branch prediction rule default < call"
+ z++
+ } else {
+ y = g(z, x, y)
+ }
+ if y+z == 3 { // ERROR "Branch prediction rule call < exit"
+ println("ha ha")
+ } else {
+ panic("help help help")
+ }
+ if x != 0 { // ERROR "Branch prediction rule default < ret"
+ for i := 0; i < x; i++ { // ERROR "Branch prediction rule stay in loop"
+ if x == 4 { // ERROR "Branch prediction rule stay in loop"
+ return a
+ }
+ for j := 0; j < y; j++ { // ERROR "Branch prediction rule stay in loop"
+ for k := 0; k < z; k++ { // ERROR "Branch prediction rule stay in loop"
+ a -= j * i
+ }
+ a += j
+ }
+ }
+ }
+ return a
+}
+
+func h(x, y, z int) int {
+ a := 0
+ for i := 0; i < x; i++ { // ERROR "Branch prediction rule stay in loop"
+ for j := 0; j < y; j++ { // ERROR "Branch prediction rule stay in loop"
+ a += j
+ if i == j { // ERROR "Branch prediction rule stay in loop"
+ break
+ }
+ a *= j
+ }
+ for k := 0; k < z; k++ { // ERROR "Branch prediction rule stay in loop"
+ a -= k
+ if i == k {
+ continue
+ }
+ a *= k
+ }
+ }
+ if a > 0 { // ERROR "Branch prediction rule default < call"
+ a = g(x, y, z)
+ } else {
+ a = -a
+ }
+ return a
+}
diff --git a/test/phiopt.go b/test/phiopt.go
new file mode 100644
index 0000000000..9b9b701124
--- /dev/null
+++ b/test/phiopt.go
@@ -0,0 +1,43 @@
+// +build amd64
+// errorcheck -0 -d=ssa/phiopt/debug=3
+
+package main
+
+func f0(a bool) bool {
+ x := false
+ if a {
+ x = true
+ } else {
+ x = false
+ }
+ return x // ERROR "converted OpPhi to OpCopy$"
+}
+
+func f1(a bool) bool {
+ x := false
+ if a {
+ x = false
+ } else {
+ x = true
+ }
+ return x // ERROR "converted OpPhi to OpNot$"
+}
+
+func f2(a, b int) bool {
+ x := true
+ if a == b {
+ x = false
+ }
+ return x // ERROR "converted OpPhi to OpNot$"
+}
+
+func f3(a, b int) bool {
+ x := false
+ if a == b {
+ x = true
+ }
+ return x // ERROR "converted OpPhi to OpCopy$"
+}
+
+func main() {
+}
diff --git a/test/prove.go b/test/prove.go
new file mode 100644
index 0000000000..0f5b8ce87f
--- /dev/null
+++ b/test/prove.go
@@ -0,0 +1,207 @@
+// +build amd64
+// errorcheck -0 -d=ssa/prove/debug=3
+
+package main
+
+func f0(a []int) int {
+ a[0] = 1
+ a[0] = 1 // ERROR "Proved IsInBounds$"
+ a[6] = 1
+ a[6] = 1 // ERROR "Proved IsInBounds$"
+ a[5] = 1
+ a[5] = 1 // ERROR "Proved IsInBounds$"
+ return 13
+}
+
+func f1(a []int) int {
+ if len(a) <= 5 {
+ return 18
+ }
+ a[0] = 1
+ a[0] = 1 // ERROR "Proved IsInBounds$"
+ a[6] = 1
+ a[6] = 1 // ERROR "Proved IsInBounds$"
+ a[5] = 1 // ERROR "Proved constant IsInBounds$"
+ a[5] = 1 // ERROR "Proved IsInBounds$"
+ return 26
+}
+
+func f2(a []int) int {
+ for i := range a {
+ a[i] = i
+ a[i] = i // ERROR "Proved IsInBounds$"
+ }
+ return 34
+}
+
+func f3(a []uint) int {
+ for i := uint(0); i < uint(len(a)); i++ {
+ a[i] = i // ERROR "Proved IsInBounds$"
+ }
+ return 41
+}
+
+func f4a(a, b, c int) int {
+ if a < b {
+ if a == b { // ERROR "Disproved Eq64$"
+ return 47
+ }
+ if a > b { // ERROR "Disproved Greater64$"
+ return 50
+ }
+ if a < b { // ERROR "Proved Less64$"
+ return 53
+ }
+ if a == b { // ERROR "Disproved Eq64$"
+ return 56
+ }
+ if a > b {
+ return 59
+ }
+ return 61
+ }
+ return 63
+}
+
+func f4b(a, b, c int) int {
+ if a <= b {
+ if a >= b {
+ if a == b { // ERROR "Proved Eq64$"
+ return 70
+ }
+ return 75
+ }
+ return 77
+ }
+ return 79
+}
+
+func f4c(a, b, c int) int {
+ if a <= b {
+ if a >= b {
+ if a != b { // ERROR "Disproved Neq64$"
+ return 73
+ }
+ return 75
+ }
+ return 77
+ }
+ return 79
+}
+
+func f4d(a, b, c int) int {
+ if a < b {
+ if a < c {
+ if a < b { // ERROR "Proved Less64$"
+ if a < c { // ERROR "Proved Less64$"
+ return 87
+ }
+ return 89
+ }
+ return 91
+ }
+ return 93
+ }
+ return 95
+}
+
+func f4e(a, b, c int) int {
+ if a < b {
+ if b > a { // ERROR "Proved Greater64$"
+ return 101
+ }
+ return 103
+ }
+ return 105
+}
+
+func f4f(a, b, c int) int {
+ if a <= b {
+ if b > a {
+ if b == a { // ERROR "Disproved Eq64$"
+ return 112
+ }
+ return 114
+ }
+ if b >= a { // ERROR "Proved Geq64$"
+ if b == a { // ERROR "Proved Eq64$"
+ return 118
+ }
+ return 120
+ }
+ return 122
+ }
+ return 124
+}
+
+func f5(a, b uint) int {
+ if a == b {
+ if a <= b { // ERROR "Proved Leq64U$"
+ return 130
+ }
+ return 132
+ }
+ return 134
+}
+
+// These comparisons are compile time constants.
+func f6a(a uint8) int {
+ if a < a { // ERROR "Disproved Less8U$"
+ return 140
+ }
+ return 151
+}
+
+func f6b(a uint8) int {
+ if a < a { // ERROR "Disproved Less8U$"
+ return 140
+ }
+ return 151
+}
+
+func f6x(a uint8) int {
+ if a > a { // ERROR "Disproved Greater8U$"
+ return 143
+ }
+ return 151
+}
+
+func f6d(a uint8) int {
+ if a <= a { // ERROR "Proved Leq8U$"
+ return 146
+ }
+ return 151
+}
+
+func f6e(a uint8) int {
+ if a >= a { // ERROR "Proved Geq8U$"
+ return 149
+ }
+ return 151
+}
+
+func f7(a []int, b int) int {
+ if b < len(a) {
+ a[b] = 3
+ if b < len(a) { // ERROR "Proved Less64$"
+ a[b] = 5 // ERROR "Proved IsInBounds$"
+ }
+ }
+ return 161
+}
+
+func f8(a, b uint) int {
+ if a == b {
+ return 166
+ }
+ if a > b {
+ return 169
+ }
+ if a < b { // ERROR "Proved Less64U$"
+ return 172
+ }
+ return 174
+}
+
+func main() {
+}
diff --git a/test/run.go b/test/run.go
index 52230efc42..8e6877995e 100644
--- a/test/run.go
+++ b/test/run.go
@@ -37,6 +37,7 @@ var (
numParallel = flag.Int("n", runtime.NumCPU(), "number of parallel tests to run")
summary = flag.Bool("summary", false, "show summary of results")
showSkips = flag.Bool("show_skips", false, "show skipped tests")
+ runSkips = flag.Bool("run_skips", false, "run skipped tests (ignore skip and build tags)")
linkshared = flag.Bool("linkshared", false, "")
updateErrors = flag.Bool("update_errors", false, "update error messages in test file based on compiler output")
runoutputLimit = flag.Int("l", defaultRunOutputLimit(), "number of parallel runoutput tests to run")
@@ -339,6 +340,9 @@ type context struct {
// shouldTest looks for build tags in a source file and returns
// whether the file should be used according to the tags.
func shouldTest(src string, goos, goarch string) (ok bool, whyNot string) {
+ if *runSkips {
+ return true, ""
+ }
for _, line := range strings.Split(src, "\n") {
line = strings.TrimSpace(line)
if strings.HasPrefix(line, "//") {
@@ -485,6 +489,9 @@ func (t *test) run() {
args = args[1:]
}
case "skip":
+ if *runSkips {
+ break
+ }
t.action = "skip"
return
default:
@@ -508,6 +515,7 @@ func (t *test) run() {
}
useTmp := true
+ ssaMain := false
runcmd := func(args ...string) ([]byte, error) {
cmd := exec.Command(args[0], args[1:]...)
var buf bytes.Buffer
@@ -516,6 +524,11 @@ func (t *test) run() {
if useTmp {
cmd.Dir = t.tempDir
cmd.Env = envForDir(cmd.Dir)
+ } else {
+ cmd.Env = os.Environ()
+ }
+ if ssaMain && os.Getenv("GOARCH") == "amd64" {
+ cmd.Env = append(cmd.Env, "GOSSAPKG=main")
}
err := cmd.Run()
if err != nil {
@@ -647,6 +660,7 @@ func (t *test) run() {
case "run":
useTmp = false
+ ssaMain = true
cmd := []string{"go", "run"}
if *linkshared {
cmd = append(cmd, "-linkshared")
@@ -682,6 +696,7 @@ func (t *test) run() {
t.err = fmt.Errorf("write tempfile:%s", err)
return
}
+ ssaMain = true
cmd = []string{"go", "run"}
if *linkshared {
cmd = append(cmd, "-linkshared")
diff --git a/test/sliceopt.go b/test/sliceopt.go
index c9d089f7d2..90ec75086e 100644
--- a/test/sliceopt.go
+++ b/test/sliceopt.go
@@ -1,3 +1,4 @@
+// +build !amd64
// errorcheck -0 -d=append,slice
// Copyright 2015 The Go Authors. All rights reserved.