...
Run Format

Source file test/goto.go

     1	// errorcheck
     2	
     3	// Copyright 2011 The Go Authors. All rights reserved.
     4	// Use of this source code is governed by a BSD-style
     5	// license that can be found in the LICENSE file.
     6	
     7	// Verify goto semantics.
     8	// Does not compile.
     9	//
    10	// Each test is in a separate function just so that if the
    11	// compiler stops processing after one error, we don't
    12	// lose other ones.
    13	
    14	package main
    15	
    16	var (
    17		i, n int
    18		x    []int
    19		c    chan int
    20		m    map[int]int
    21		s    string
    22	)
    23	
    24	// goto after declaration okay
    25	func _() {
    26		x := 1
    27		goto L
    28	L:
    29		_ = x
    30	}
    31	
    32	// goto before declaration okay
    33	func _() {
    34		goto L
    35	L:
    36		x := 1
    37		_ = x
    38	}
    39	
    40	// goto across declaration not okay
    41	func _() {
    42		goto L // ERROR "goto L jumps over declaration of x at LINE+1|goto jumps over declaration"
    43		x := 1 // GCCGO_ERROR "defined here"
    44		_ = x
    45	L:
    46	}
    47	
    48	// goto across declaration in inner scope okay
    49	func _() {
    50		goto L
    51		{
    52			x := 1
    53			_ = x
    54		}
    55	L:
    56	}
    57	
    58	// goto across declaration after inner scope not okay
    59	func _() {
    60		goto L // ERROR "goto L jumps over declaration of x at LINE+5|goto jumps over declaration"
    61		{
    62			x := 1
    63			_ = x
    64		}
    65		x := 1 // GCCGO_ERROR "defined here"
    66		_ = x
    67	L:
    68	}
    69	
    70	// goto across declaration in reverse okay
    71	func _() {
    72	L:
    73		x := 1
    74		_ = x
    75		goto L
    76	}
    77	
    78	// error shows first offending variable
    79	func _() {
    80		goto L // ERROR "goto L jumps over declaration of x at LINE+1|goto jumps over declaration"
    81		x := 1 // GCCGO_ERROR "defined here"
    82		_ = x
    83		y := 1
    84		_ = y
    85	L:
    86	}
    87	
    88	// goto not okay even if code path is dead
    89	func _() {
    90		goto L // ERROR "goto L jumps over declaration of x at LINE+1|goto jumps over declaration"
    91		x := 1 // GCCGO_ERROR "defined here"
    92		_ = x
    93		y := 1
    94		_ = y
    95		return
    96	L:
    97	}
    98	
    99	// goto into outer block okay
   100	func _() {
   101		{
   102			goto L
   103		}
   104	L:
   105	}
   106	
   107	// goto backward into outer block okay
   108	func _() {
   109	L:
   110		{
   111			goto L
   112		}
   113	}
   114	
   115	// goto into inner block not okay
   116	func _() {
   117		goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
   118		{      // GCCGO_ERROR "block starts here"
   119		L:
   120		}
   121	}
   122	
   123	// goto backward into inner block still not okay
   124	func _() {
   125		{ // GCCGO_ERROR "block starts here"
   126		L:
   127		}
   128		goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
   129	}
   130	
   131	// error shows first (outermost) offending block
   132	func _() {
   133		goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
   134		{
   135			{
   136				{ // GCCGO_ERROR "block starts here"
   137				L:
   138				}
   139			}
   140		}
   141	}
   142	
   143	// error prefers block diagnostic over declaration diagnostic
   144	func _() {
   145		goto L // ERROR "goto L jumps into block starting at LINE+3|goto jumps into block"
   146		x := 1
   147		_ = x
   148		{ // GCCGO_ERROR "block starts here"
   149		L:
   150		}
   151	}
   152	
   153	// many kinds of blocks, all invalid to jump into or among,
   154	// but valid to jump out of
   155	
   156	// if
   157	
   158	func _() {
   159	L:
   160		if true {
   161			goto L
   162		}
   163	}
   164	
   165	func _() {
   166	L:
   167		if true {
   168			goto L
   169		} else {
   170		}
   171	}
   172	
   173	func _() {
   174	L:
   175		if false {
   176		} else {
   177			goto L
   178		}
   179	}
   180	
   181	func _() {
   182		goto L    // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
   183		if true { // GCCGO_ERROR "block starts here"
   184		L:
   185		}
   186	}
   187	
   188	func _() {
   189		goto L    // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
   190		if true { // GCCGO_ERROR "block starts here"
   191		L:
   192		} else {
   193		}
   194	}
   195	
   196	func _() {
   197		goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
   198		if true {
   199		} else { // GCCGO_ERROR "block starts here"
   200		L:
   201		}
   202	}
   203	
   204	func _() {
   205		if false { // GCCGO_ERROR "block starts here"
   206		L:
   207		} else {
   208			goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
   209		}
   210	}
   211	
   212	func _() {
   213		if true {
   214			goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
   215		} else { // GCCGO_ERROR "block starts here"
   216		L:
   217		}
   218	}
   219	
   220	func _() {
   221		if true {
   222			goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
   223		} else if false { // GCCGO_ERROR "block starts here"
   224		L:
   225		}
   226	}
   227	
   228	func _() {
   229		if true {
   230			goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
   231		} else if false { // GCCGO_ERROR "block starts here"
   232		L:
   233		} else {
   234		}
   235	}
   236	
   237	func _() {
   238		// This one is tricky.  There is an implicit scope
   239		// starting at the second if statement, and it contains
   240		// the final else, so the outermost offending scope
   241		// really is LINE+1 (like in the previous test),
   242		// even though it looks like it might be LINE+3 instead.
   243		if true {
   244			goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
   245		} else if false {
   246		} else { // GCCGO_ERROR "block starts here"
   247		L:
   248		}
   249	}
   250	
   251	/* Want to enable these tests but gofmt mangles them.  Issue 1972.
   252	
   253	func _() {
   254		// This one is okay, because the else is in the
   255		// implicit whole-if block and has no inner block
   256		// (no { }) around it.
   257		if true {
   258			goto L
   259		} else
   260			L:
   261	}
   262	
   263	func _() {
   264		// Still not okay.
   265		if true {	//// GCCGO_ERROR "block starts here"
   266		L:
   267		} else
   268			goto L //// ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
   269	}
   270	
   271	*/
   272	
   273	// for
   274	
   275	func _() {
   276		for {
   277			goto L
   278		}
   279	L:
   280	}
   281	
   282	func _() {
   283		for {
   284			goto L
   285		L:
   286		}
   287	}
   288	
   289	func _() {
   290		for { // GCCGO_ERROR "block starts here"
   291		L:
   292		}
   293		goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
   294	}
   295	
   296	func _() {
   297		for { // GCCGO_ERROR "block starts here"
   298			goto L
   299		L1:
   300		}
   301	L:
   302		goto L1 // ERROR "goto L1 jumps into block starting at LINE-5|goto jumps into block"
   303	}
   304	
   305	func _() {
   306		for i < n { // GCCGO_ERROR "block starts here"
   307		L:
   308		}
   309		goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
   310	}
   311	
   312	func _() {
   313		for i = 0; i < n; i++ { // GCCGO_ERROR "block starts here"
   314		L:
   315		}
   316		goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
   317	}
   318	
   319	func _() {
   320		for i = range x { // GCCGO_ERROR "block starts here"
   321		L:
   322		}
   323		goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
   324	}
   325	
   326	func _() {
   327		for i = range c { // GCCGO_ERROR "block starts here"
   328		L:
   329		}
   330		goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
   331	}
   332	
   333	func _() {
   334		for i = range m { // GCCGO_ERROR "block starts here"
   335		L:
   336		}
   337		goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
   338	}
   339	
   340	func _() {
   341		for i = range s { // GCCGO_ERROR "block starts here"
   342		L:
   343		}
   344		goto L // ERROR "goto L jumps into block starting at LINE-3|goto jumps into block"
   345	}
   346	
   347	// switch
   348	
   349	func _() {
   350	L:
   351		switch i {
   352		case 0:
   353			goto L
   354		}
   355	}
   356	
   357	func _() {
   358	L:
   359		switch i {
   360		case 0:
   361	
   362		default:
   363			goto L
   364		}
   365	}
   366	
   367	func _() {
   368		switch i {
   369		case 0:
   370	
   371		default:
   372		L:
   373			goto L
   374		}
   375	}
   376	
   377	func _() {
   378		switch i {
   379		case 0:
   380	
   381		default:
   382			goto L
   383		L:
   384		}
   385	}
   386	
   387	func _() {
   388		switch i {
   389		case 0:
   390			goto L
   391		L:
   392			;
   393		default:
   394		}
   395	}
   396	
   397	func _() {
   398		goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
   399		switch i {
   400		case 0:
   401		L: // GCCGO_ERROR "block starts here"
   402		}
   403	}
   404	
   405	func _() {
   406		goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
   407		switch i {
   408		case 0:
   409		L: // GCCGO_ERROR "block starts here"
   410			;
   411		default:
   412		}
   413	}
   414	
   415	func _() {
   416		goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
   417		switch i {
   418		case 0:
   419		default:
   420		L: // GCCGO_ERROR "block starts here"
   421		}
   422	}
   423	
   424	func _() {
   425		switch i {
   426		default:
   427			goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
   428		case 0:
   429		L: // GCCGO_ERROR "block starts here"
   430		}
   431	}
   432	
   433	func _() {
   434		switch i {
   435		case 0:
   436		L: // GCCGO_ERROR "block starts here"
   437			;
   438		default:
   439			goto L // ERROR "goto L jumps into block starting at LINE-4|goto jumps into block"
   440		}
   441	}
   442	
   443	// select
   444	// different from switch.  the statement has no implicit block around it.
   445	
   446	func _() {
   447	L:
   448		select {
   449		case <-c:
   450			goto L
   451		}
   452	}
   453	
   454	func _() {
   455	L:
   456		select {
   457		case c <- 1:
   458	
   459		default:
   460			goto L
   461		}
   462	}
   463	
   464	func _() {
   465		select {
   466		case <-c:
   467	
   468		default:
   469		L:
   470			goto L
   471		}
   472	}
   473	
   474	func _() {
   475		select {
   476		case c <- 1:
   477	
   478		default:
   479			goto L
   480		L:
   481		}
   482	}
   483	
   484	func _() {
   485		select {
   486		case <-c:
   487			goto L
   488		L:
   489			;
   490		default:
   491		}
   492	}
   493	
   494	func _() {
   495		goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
   496		select {
   497		case c <- 1:
   498		L: // GCCGO_ERROR "block starts here"
   499		}
   500	}
   501	
   502	func _() {
   503		goto L // ERROR "goto L jumps into block starting at LINE+2|goto jumps into block"
   504		select {
   505		case c <- 1:
   506		L: // GCCGO_ERROR "block starts here"
   507			;
   508		default:
   509		}
   510	}
   511	
   512	func _() {
   513		goto L // ERROR "goto L jumps into block starting at LINE+3|goto jumps into block"
   514		select {
   515		case <-c:
   516		default:
   517		L: // GCCGO_ERROR "block starts here"
   518		}
   519	}
   520	
   521	func _() {
   522		select {
   523		default:
   524			goto L // ERROR "goto L jumps into block starting at LINE+1|goto jumps into block"
   525		case <-c:
   526		L: // GCCGO_ERROR "block starts here"
   527		}
   528	}
   529	
   530	func _() {
   531		select {
   532		case <-c:
   533		L: // GCCGO_ERROR "block starts here"
   534			;
   535		default:
   536			goto L // ERROR "goto L jumps into block starting at LINE-4|goto jumps into block"
   537		}
   538	}
   539	

View as plain text