1// run
2
3//go:build !nacl && !js && !wasip1
4
5// Copyright 2018 The Go Authors. All rights reserved.
6// Use of this source code is governed by a BSD-style
7// license that can be found in the LICENSE file.
8
9// Ensure that label redefinition errors print out
10// a column number that matches the start of the current label's
11// definition instead of the label delimiting token ":"
12
13package main
14
15import (
16	"bytes"
17	"fmt"
18	"io/ioutil"
19	"log"
20	"os"
21	"os/exec"
22	"path/filepath"
23	"regexp"
24)
25
26func main() {
27	tmpdir, err := ioutil.TempDir("", "issue26411")
28	if err != nil {
29		log.Fatalf("Failed to create temporary directory: %v", err)
30	}
31	defer os.RemoveAll(tmpdir)
32
33	tests := []struct {
34		code   string
35		errors []string
36	}{
37		{
38			code: `
39package main
40
41func main() {
42foo:
43foo:
44}
45`,
46			errors: []string{
47				"^.+:5:1: label foo defined and not used\n",
48				".+:6:1: label foo already defined at .+:5:1\n$",
49			},
50		},
51		{
52			code: `
53package main
54
55func main() {
56
57            bar:
58   bar:
59bar:
60bar            :
61}
62`,
63
64			errors: []string{
65				"^.+:6:13: label bar defined and not used\n",
66				".+:7:4: label bar already defined at .+:6:13\n",
67				".+:8:1: label bar already defined at .+:6:13\n",
68				".+:9:1: label bar already defined at .+:6:13\n$",
69			},
70		},
71	}
72
73	for i, test := range tests {
74		filename := filepath.Join(tmpdir, fmt.Sprintf("%d.go", i))
75		if err := ioutil.WriteFile(filename, []byte(test.code), 0644); err != nil {
76			log.Printf("#%d: failed to create file %s", i, filename)
77			continue
78		}
79		output, _ := exec.Command("go", "tool", "compile", "-p=p", filename).CombinedOutput()
80
81		// remove each matching error from the output
82		for _, err := range test.errors {
83			rx := regexp.MustCompile(err)
84			match := rx.Find(output)
85			output = bytes.Replace(output, match, nil, 1) // remove match (which might be nil) from output
86		}
87
88		// at this point all output should have been consumed
89		if len(output) != 0 {
90			log.Printf("Test case %d has unmatched errors:\n%s", i, output)
91		}
92	}
93}
94