1// run 2 3// Copyright 2021 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// Check that the compiler refuses excessively long constants. 8 9package main 10 11import ( 12 "bytes" 13 "fmt" 14 "io/ioutil" 15 "log" 16 "os" 17 "os/exec" 18 "path/filepath" 19 "runtime" 20 "strings" 21) 22 23// testProg creates a package called name, with path dir/name.go, 24// which declares an untyped constant of the given length. 25// testProg compiles this package and checks for the absence or 26// presence of a constant literal error. 27func testProg(dir, name string, length int, msg string) { 28 var buf bytes.Buffer 29 30 fmt.Fprintf(&buf, 31 "package %s; const _ = 0b%s // %d bits", 32 name, strings.Repeat("1", length), length, 33 ) 34 35 filename := filepath.Join(dir, fmt.Sprintf("%s.go", name)) 36 if err := os.WriteFile(filename, buf.Bytes(), 0666); err != nil { 37 log.Fatal(err) 38 } 39 40 cmd := exec.Command("go", "tool", "compile", "-p=p", filename) 41 cmd.Dir = dir 42 output, err := cmd.CombinedOutput() 43 44 if msg == "" { 45 // no error expected 46 if err != nil { 47 log.Fatalf("%s: compile failed unexpectedly: %v", name, err) 48 } 49 return 50 } 51 52 // error expected 53 if err == nil { 54 log.Fatalf("%s: compile succeeded unexpectedly", name) 55 } 56 if !bytes.Contains(output, []byte(msg)) { 57 log.Fatalf("%s: wrong compiler error message:\n%s\n", name, output) 58 } 59} 60 61func main() { 62 if runtime.GOOS == "js" || runtime.GOOS == "wasip1" || runtime.Compiler != "gc" { 63 return 64 } 65 66 dir, err := ioutil.TempDir("", "const7_") 67 if err != nil { 68 log.Fatalf("creating temp dir: %v\n", err) 69 } 70 defer os.RemoveAll(dir) 71 72 const bitLimit = 512 73 const charLimit = 10000 // compiler-internal constant length limit 74 testProg(dir, "x1", bitLimit, "") 75 testProg(dir, "x2", bitLimit+1, "constant overflow") 76 testProg(dir, "x3", charLimit-2, "constant overflow") // -2 because literal contains 0b prefix 77 testProg(dir, "x4", charLimit-1, "excessively long constant") 78} 79