summaryrefslogtreecommitdiff
path: root/test/const7.go
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2021-02-02 13:20:03 -0800
committerRobert Griesemer <gri@golang.org>2021-02-03 20:22:34 +0000
commitc910fd7b771cfbfc1b11a6eef750f835bf66c96c (patch)
treeaf1361479316deaf3d4141034652ec423c576a51 /test/const7.go
parent3db6e18468d9e5c8f5fcfece26b5b666f86e9742 (diff)
downloadgo-git-c910fd7b771cfbfc1b11a6eef750f835bf66c96c.tar.gz
[dev.typeparams] cmd/compile: refuse excessively long constants
The compiler uses 512 bit of precision for untyped constant arithmetic but didn't restrict the length of incoming constant literals in any way, possibly opening the door for excessively long constants that could bring compilation to a crawl. Add a simple check that refuses excessively long constants. Add test. Change-Id: I797cb2a8e677b8da2864eb92d686d271ab8a004d Reviewed-on: https://go-review.googlesource.com/c/go/+/289049 Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
Diffstat (limited to 'test/const7.go')
-rw-r--r--test/const7.go77
1 files changed, 77 insertions, 0 deletions
diff --git a/test/const7.go b/test/const7.go
new file mode 100644
index 0000000000..9ffd678fc5
--- /dev/null
+++ b/test/const7.go
@@ -0,0 +1,77 @@
+// run
+
+// Copyright 2021 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.
+
+// Check that the compiler refuses excessively long constants.
+
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "runtime"
+ "strings"
+)
+
+// testProg creates a package called name, with path dir/name.go,
+// which declares an untyped constant of the given length.
+// testProg compiles this package and checks for the absence or
+// presence of a constant literal error.
+func testProg(dir, name string, G_option, length int, ok bool) {
+ var buf bytes.Buffer
+
+ fmt.Fprintf(&buf,
+ "package %s; const _ = %s // %d digits",
+ name, strings.Repeat("9", length), length,
+ )
+
+ filename := filepath.Join(dir, fmt.Sprintf("%s.go", name))
+ if err := os.WriteFile(filename, buf.Bytes(), 0666); err != nil {
+ log.Fatal(err)
+ }
+
+ cmd := exec.Command("go", "tool", "compile", fmt.Sprintf("-G=%d", G_option), filename)
+ cmd.Dir = dir
+ output, err := cmd.CombinedOutput()
+
+ if ok {
+ // no error expected
+ if err != nil {
+ log.Fatalf("%s: compile failed unexpectedly: %v", name, err)
+ }
+ return
+ }
+
+ // error expected
+ if err == nil {
+ log.Fatalf("%s: compile succeeded unexpectedly", name)
+ }
+ if !bytes.Contains(output, []byte("excessively long constant")) {
+ log.Fatalf("%s: wrong compiler error message:\n%s\n", name, output)
+ }
+}
+
+func main() {
+ if runtime.GOOS == "js" || runtime.Compiler != "gc" {
+ return
+ }
+
+ dir, err := ioutil.TempDir("", "const7_")
+ if err != nil {
+ log.Fatalf("creating temp dir: %v\n", err)
+ }
+ defer os.RemoveAll(dir)
+
+ const limit = 10000 // compiler-internal constant length limit
+ testProg(dir, "x1", 0, limit, true) // -G=0
+ testProg(dir, "x2", 0, limit+1, false) // -G=0
+ testProg(dir, "x1", 1, limit, true) // -G=1 (new type checker)
+ testProg(dir, "x2", 1, limit+1, false) // -G=1 (new type checker)
+}