diff options
| author | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2016-03-01 21:36:45 +0000 |
|---|---|---|
| committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2016-03-01 21:36:45 +0000 |
| commit | a6fb2aede7c8d47b4d913eb83fa45bbeca76c433 (patch) | |
| tree | 1dd5039e5515959a8d162fbdac964663dd2ec778 /test | |
| parent | 998aaf8a64b7d90269815a2ae9d778da519d0a87 (diff) | |
| parent | 9d854fd44ae669f60c15133a4d2ce407ea2bccc4 (diff) | |
| download | go-a6fb2aede7c8d47b4d913eb83fa45bbeca76c433.tar.xz | |
Merge "Merge branch 'dev.ssa' into mergebranch"
Diffstat (limited to 'test')
| -rw-r--r-- | test/fixedbugs/issue12347.go | 16 | ||||
| -rw-r--r-- | test/goto.go | 72 | ||||
| -rw-r--r-- | test/label.go | 7 | ||||
| -rw-r--r-- | test/label1.go | 32 | ||||
| -rw-r--r-- | test/live.go | 1 | ||||
| -rw-r--r-- | test/live2.go | 1 | ||||
| -rw-r--r-- | test/nilcheck.go | 98 | ||||
| -rw-r--r-- | test/nilptr3.go | 2 | ||||
| -rw-r--r-- | test/nilptr3_ssa.go | 209 | ||||
| -rw-r--r-- | test/nosplit.go | 5 | ||||
| -rw-r--r-- | test/opt_branchlikely.go | 85 | ||||
| -rw-r--r-- | test/phiopt.go | 43 | ||||
| -rw-r--r-- | test/prove.go | 207 | ||||
| -rw-r--r-- | test/run.go | 15 | ||||
| -rw-r--r-- | test/sliceopt.go | 1 |
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. |
