1// run 2//go:build !nacl && !js && !wasip1 && !gccgo 3 4// Copyright 2017 The Go Authors. All rights reserved. 5// Use of this source code is governed by a BSD-style 6// license that can be found in the LICENSE file. 7 8// ensure that panic(x) where x is a numeric type displays a readable number 9package main 10 11import ( 12 "bytes" 13 "fmt" 14 "io/ioutil" 15 "log" 16 "os" 17 "os/exec" 18 "path/filepath" 19) 20 21const fn = ` 22package main 23 24import "errors" 25type S struct { 26 27} 28func (s S) String() string { 29 return "s-stringer" 30} 31func main() { 32 _ = errors.New 33 panic(%s(%s)) 34} 35` 36 37func main() { 38 tempDir, err := ioutil.TempDir("", "") 39 if err != nil { 40 log.Fatal(err) 41 } 42 defer os.RemoveAll(tempDir) 43 tmpFile := filepath.Join(tempDir, "tmp.go") 44 45 for _, tc := range []struct { 46 Type string 47 Input string 48 Expect string 49 }{ 50 {"", "nil", "panic: panic called with nil argument"}, 51 {"errors.New", `"test"`, "panic: test"}, 52 {"S", "S{}", "panic: s-stringer"}, 53 {"byte", "8", "panic: 8"}, 54 {"rune", "8", "panic: 8"}, 55 {"int", "8", "panic: 8"}, 56 {"int8", "8", "panic: 8"}, 57 {"int16", "8", "panic: 8"}, 58 {"int32", "8", "panic: 8"}, 59 {"int64", "8", "panic: 8"}, 60 {"uint", "8", "panic: 8"}, 61 {"uint8", "8", "panic: 8"}, 62 {"uint16", "8", "panic: 8"}, 63 {"uint32", "8", "panic: 8"}, 64 {"uint64", "8", "panic: 8"}, 65 {"uintptr", "8", "panic: 8"}, 66 {"bool", "true", "panic: true"}, 67 {"complex64", "8 + 16i", "panic: (+8.000000e+000+1.600000e+001i)"}, 68 {"complex128", "8+16i", "panic: (+8.000000e+000+1.600000e+001i)"}, 69 {"string", `"test"`, "panic: test"}} { 70 71 b := bytes.Buffer{} 72 fmt.Fprintf(&b, fn, tc.Type, tc.Input) 73 74 err = ioutil.WriteFile(tmpFile, b.Bytes(), 0644) 75 if err != nil { 76 log.Fatal(err) 77 } 78 79 cmd := exec.Command("go", "run", tmpFile) 80 var buf bytes.Buffer 81 cmd.Stdout = &buf 82 cmd.Stderr = &buf 83 cmd.Env = os.Environ() 84 cmd.Run() // ignore err as we expect a panic 85 86 out := buf.Bytes() 87 panicIdx := bytes.Index(out, []byte("panic: ")) 88 if panicIdx == -1 { 89 log.Fatalf("expected a panic in output for %s, got: %s", tc.Type, out) 90 } 91 eolIdx := bytes.IndexByte(out[panicIdx:], '\n') + panicIdx 92 if panicIdx == -1 { 93 log.Fatalf("expected a newline in output for %s after the panic, got: %s", tc.Type, out) 94 } 95 out = out[0:eolIdx] 96 if string(out) != tc.Expect { 97 log.Fatalf("expected '%s' for panic(%s(%s)), got %s", tc.Expect, tc.Type, tc.Input, out) 98 } 99 } 100} 101