]> Cypherpunks repositories - gostls13.git/commitdiff
test: test of goto restrictions
authorRuss Cox <rsc@golang.org>
Mon, 20 Jun 2011 18:06:00 +0000 (14:06 -0400)
committerRuss Cox <rsc@golang.org>
Mon, 20 Jun 2011 18:06:00 +0000 (14:06 -0400)
R=gri, iant, bradfitz, fvbommel, r
CC=golang-dev
https://golang.org/cl/4652041

test/errchk
test/goto.go [new file with mode: 0644]

index fbb021ce41768cb6e1a49c954da39bb923e70724..e89d759508819a9f05e64cc7b2ac45e358da9802 100755 (executable)
@@ -81,6 +81,19 @@ sub chk {
                        next;
                }
                $regexp = $1;
+               
+               # Turn relative line number in message into absolute line number.
+               if($regexp =~ /LINE(([+-])([0-9]+))?/) {
+                       my $n = $line;
+                       if(defined($1)) {
+                               if($2 eq "+") {
+                                       $n += int($3);
+                               } else {
+                                       $n -= int($3);
+                               }
+                       }
+                       $regexp = "$`$file:$n$'";
+               }
 
                @errmsg = grep { /$file:$line[:[]/ } @out;
                @out = grep { !/$file:$line[:[]/ } @out;
@@ -93,6 +106,9 @@ sub chk {
                if(@match == 0) {
                        bug();
                        print STDERR "errchk: $file:$line: error message does not match '$regexp'\n";
+                       foreach my $l (@errmsg) {
+                               print STDERR "> $l";
+                       }
                        next;
                }
        }
diff --git a/test/goto.go b/test/goto.go
new file mode 100644 (file)
index 0000000..0a50938
--- /dev/null
@@ -0,0 +1,535 @@
+// errchk $G -e $D/$F.go
+
+// Copyright 2011 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Each test is in a separate function just so that if the
+// compiler stops processing after one error, we don't
+// lose other ones.
+
+package main
+
+var (
+       i, n int
+       x    []int
+       c    chan int
+       m    map[int]int
+       s    string
+)
+
+// goto after declaration okay
+func _() {
+       x := 1
+       goto L
+L:
+       _ = x
+}
+
+// goto before declaration okay
+func _() {
+       goto L
+L:
+       x := 1
+       _ = x
+}
+
+// goto across declaration not okay
+func _() {
+       goto L // ERROR "goto L jumps over declaration of x at LINE+1"
+       x := 1
+       _ = x
+L:
+}
+
+// goto across declaration in inner scope okay
+func _() {
+       goto L
+       {
+               x := 1
+               _ = x
+       }
+L:
+}
+
+// goto across declaration after inner scope not okay
+func _() {
+       goto L // ERROR "goto L jumps over declaration of x at LINE+5"
+       {
+               x := 1
+               _ = x
+       }
+       x := 1
+       _ = x
+L:
+}
+
+// goto across declaration in reverse okay
+func _() {
+L:
+       x := 1
+       _ = x
+       goto L
+}
+
+// error shows first offending variable
+func _() {
+       goto L // ERROR "goto L jumps over declaration of x at LINE+1"
+       x := 1
+       _ = x
+       y := 1
+       _ = y
+L:
+}
+
+// goto not okay even if code path is dead
+func _() {
+       goto L // ERROR "goto L jumps over declaration of x at LINE+1"
+       x := 1
+       _ = x
+       y := 1
+       _ = y
+       return
+L:
+}
+
+// goto into outer block okay
+func _() {
+       {
+               goto L
+       }
+L:
+}
+
+// goto backward into outer block okay
+func _() {
+L:
+       {
+               goto L
+       }
+}
+
+// goto into inner block not okay
+func _() {
+       goto L // ERROR "goto L jumps into block starting at LINE+1"
+       {
+       L:
+       }
+}
+
+// goto backward into inner block still not okay
+func _() {
+       {
+       L:
+       }
+       goto L // ERROR "goto L jumps into block starting at LINE-3"
+}
+
+// error shows first (outermost) offending block
+func _() {
+       goto L // ERROR "goto L jumps into block starting at LINE+1"
+       {
+               {
+                       {
+                       L:
+                       }
+               }
+       }
+}
+
+// error prefers block diagnostic over declaration diagnostic
+func _() {
+       goto L // ERROR "goto L jumps into block starting at LINE+3"
+       x := 1
+       _ = x
+       {
+       L:
+       }
+}
+
+// many kinds of blocks, all invalid to jump into or among,
+// but valid to jump out of
+
+// if
+
+func _() {
+L:
+       if true {
+               goto L
+       }
+}
+
+func _() {
+L:
+       if true {
+               goto L
+       } else {
+       }
+}
+
+func _() {
+L:
+       if false {
+       } else {
+               goto L
+       }
+}
+
+func _() {
+       goto L // ERROR "goto L jumps into block starting at LINE+1"
+       if true {
+       L:
+       }
+}
+
+func _() {
+       goto L // ERROR "goto L jumps into block starting at LINE+1"
+       if true {
+       L:
+       } else {
+       }
+}
+
+func _() {
+       goto L // ERROR "goto L jumps into block starting at LINE+1"
+       if true {
+       } else {
+       L:
+       }
+}
+
+func _() {
+       if false {
+       L:
+       } else {
+               goto L // ERROR "goto L jumps into block starting at LINE-3"
+       }
+}
+
+func _() {
+       if true {
+               goto L // ERROR "goto L jumps into block starting at LINE+1"
+       } else {
+       L:
+       }
+}
+
+func _() {
+       if true {
+               goto L // ERROR "goto L jumps into block starting at LINE+1"
+       } else if false {
+       L:
+       }
+}
+
+func _() {
+       if true {
+               goto L // ERROR "goto L jumps into block starting at LINE+1"
+       } else if false {
+       L:
+       } else {
+       }
+}
+
+func _() {
+       // This one is tricky.  There is an implicit scope
+       // starting at the second if statement, and it contains
+       // the final else, so the outermost offending scope
+       // really is LINE+1 (like in the previous test),
+       // even though it looks like it might be LINE+3 instead.
+       if true {
+               goto L // ERROR "goto L jumps into block starting at LINE+1"
+       } else if false {
+       } else {
+       L:
+       }
+}
+
+/* Want to enable these tests but gofmt mangles them.  Issue 1972.
+
+func _() {
+       // This one is okay, because the else is in the
+       // implicit whole-if block and has no inner block
+       // (no { }) around it.
+       if true {
+               goto L
+       } else
+               L:
+}
+
+func _() {
+       // Still not okay.
+       if true {
+       L:
+       } else
+               goto L //// ERROR "goto L jumps into block starting at LINE-3"
+}
+
+*/
+
+// for
+
+func _() {
+       for {
+               goto L
+       }
+L:
+}
+
+func _() {
+       for {
+               goto L
+       L:
+       }
+}
+
+func _() {
+       for {
+       L:
+       }
+       goto L // ERROR "goto L jumps into block starting at LINE-3"
+}
+
+func _() {
+       for {
+               goto L
+       L1:
+       }
+L:
+       goto L1 // ERROR "goto L1 jumps into block starting at LINE-5"
+}
+
+func _() {
+       for i < n {
+       L:
+       }
+       goto L // ERROR "goto L jumps into block starting at LINE-3"
+}
+
+func _() {
+       for i = 0; i < n; i++ {
+       L:
+       }
+       goto L // ERROR "goto L jumps into block starting at LINE-3"
+}
+
+func _() {
+       for i = range x {
+       L:
+       }
+       goto L // ERROR "goto L jumps into block starting at LINE-3"
+}
+
+func _() {
+       for i = range c {
+       L:
+       }
+       goto L // ERROR "goto L jumps into block starting at LINE-3"
+}
+
+func _() {
+       for i = range m {
+       L:
+       }
+       goto L // ERROR "goto L jumps into block starting at LINE-3"
+}
+
+func _() {
+       for i = range s {
+       L:
+       }
+       goto L // ERROR "goto L jumps into block starting at LINE-3"
+}
+
+// switch
+
+func _() {
+L:
+       switch i {
+       case 0:
+               goto L
+       }
+}
+
+func _() {
+L:
+       switch i {
+       case 0:
+
+       default:
+               goto L
+       }
+}
+
+func _() {
+       switch i {
+       case 0:
+
+       default:
+       L:
+               goto L
+       }
+}
+
+func _() {
+       switch i {
+       case 0:
+
+       default:
+               goto L
+       L:
+       }
+}
+
+func _() {
+       switch i {
+       case 0:
+               goto L
+       L:
+               ;
+       default:
+       }
+}
+
+func _() {
+       goto L // ERROR "goto L jumps into block starting at LINE+1"
+       switch i {
+       case 0:
+       L:
+       }
+}
+
+func _() {
+       goto L // ERROR "goto L jumps into block starting at LINE+1"
+       switch i {
+       case 0:
+       L:
+               ;
+       default:
+       }
+}
+
+func _() {
+       goto L // ERROR "goto L jumps into block starting at LINE+1"
+       switch i {
+       case 0:
+       default:
+       L:
+       }
+}
+
+func _() {
+       switch i {
+       default:
+               goto L // ERROR "goto L jumps into block starting at LINE+1"
+       case 0:
+       L:
+       }
+}
+
+func _() {
+       switch i {
+       case 0:
+       L:
+               ;
+       default:
+               goto L // ERROR "goto L jumps into block starting at LINE-4"
+       }
+}
+
+// select
+// different from switch.  the statement has no implicit block around it.
+
+func _() {
+L:
+       select {
+       case <-c:
+               goto L
+       }
+}
+
+func _() {
+L:
+       select {
+       case c <- 1:
+
+       default:
+               goto L
+       }
+}
+
+func _() {
+       select {
+       case <-c:
+
+       default:
+       L:
+               goto L
+       }
+}
+
+func _() {
+       select {
+       case c <- 1:
+
+       default:
+               goto L
+       L:
+       }
+}
+
+func _() {
+       select {
+       case <-c:
+               goto L
+       L:
+               ;
+       default:
+       }
+}
+
+func _() {
+       goto L // ERROR "goto L jumps into block starting at LINE+2"
+       select {
+       case c <- 1:
+       L:
+       }
+}
+
+func _() {
+       goto L // ERROR "goto L jumps into block starting at LINE+2"
+       select {
+       case c <- 1:
+       L:
+               ;
+       default:
+       }
+}
+
+func _() {
+       goto L // ERROR "goto L jumps into block starting at LINE+3"
+       select {
+       case <-c:
+       default:
+       L:
+       }
+}
+
+func _() {
+       select {
+       default:
+               goto L // ERROR "goto L jumps into block starting at LINE+1"
+       case <-c:
+       L:
+       }
+}
+
+func _() {
+       select {
+       case <-c:
+       L:
+               ;
+       default:
+               goto L // ERROR "goto L jumps into block starting at LINE-4"
+       }
+}