Fixes #54280.
Change-Id: I44a31daaace50bc90c96cd36387bd1a009d6a287
Reviewed-on: https://go-review.googlesource.com/c/go/+/424055
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
// Untyped integer values must not grow arbitrarily.
const prec = 512 // 512 is the constant precision
if x.val.Kind() == constant.Int && constant.BitLen(x.val) > prec {
- check.errorf(opPos(x.expr), "constant %s overflow", opName(x.expr))
+ op := opName(x.expr)
+ if op != "" {
+ op += " "
+ }
+ check.errorf(opPos(x.expr), "constant %soverflow", op)
x.val = constant.MakeUnknown()
}
}
check.errorf(e, "malformed constant: %s", e.Value)
goto Error
}
+ // Ensure that integer values don't overflow (issue #54280).
+ x.expr = e // make sure that check.overflow below has an error position
+ check.overflow(x)
case *syntax.FuncLit:
if sig, ok := check.typ(e.Type).(*Signature); ok {
--- /dev/null
+// Copyright 2022 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.
+
+package p
+
+const C = 912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912 // ERROR constant overflow
}
func TestLongConstants(t *testing.T) {
- format := "package longconst\n\nconst _ = %s\nconst _ = %s // ERROR excessively long constant"
+ format := "package longconst\n\nconst _ = %s /* ERROR constant overflow */ \nconst _ = %s // ERROR excessively long constant"
src := fmt.Sprintf(format, strings.Repeat("1", 9999), strings.Repeat("1", 10001))
testFiles(t, nil, []string{"longconst.go"}, [][]byte{[]byte(src)}, false, nil)
}
// Untyped integer values must not grow arbitrarily.
const prec = 512 // 512 is the constant precision
if x.val.Kind() == constant.Int && constant.BitLen(x.val) > prec {
- check.errorf(atPos(opPos), _InvalidConstVal, "constant %s overflow", opName(x.expr))
+ op := opName(x.expr)
+ if op != "" {
+ op += " "
+ }
+ check.errorf(atPos(opPos), _InvalidConstVal, "constant %soverflow", op)
x.val = constant.MakeUnknown()
}
}
check.errorf(e, _InvalidConstVal, "malformed constant: %s", e.Value)
goto Error
}
+ // Ensure that integer values don't overflow (issue #54280).
+ check.overflow(x, e.Pos())
case *ast.FuncLit:
if sig, ok := check.typ(e.Type).(*Signature); ok {
--- /dev/null
+// Copyright 2022 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.
+
+package p
+
+const C = 912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912 // ERROR constant overflow
// 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, length int, ok bool) {
+func testProg(dir, name string, length int, msg string) {
var buf bytes.Buffer
fmt.Fprintf(&buf,
- "package %s; const _ = %s // %d digits",
- name, strings.Repeat("9", length), length,
+ "package %s; const _ = 0b%s // %d bits",
+ name, strings.Repeat("1", length), length,
)
filename := filepath.Join(dir, fmt.Sprintf("%s.go", name))
cmd.Dir = dir
output, err := cmd.CombinedOutput()
- if ok {
+ if msg == "" {
// no error expected
if err != nil {
log.Fatalf("%s: compile failed unexpectedly: %v", name, err)
if err == nil {
log.Fatalf("%s: compile succeeded unexpectedly", name)
}
- if !bytes.Contains(output, []byte("excessively long constant")) {
+ if !bytes.Contains(output, []byte(msg)) {
log.Fatalf("%s: wrong compiler error message:\n%s\n", name, output)
}
}
}
defer os.RemoveAll(dir)
- const limit = 10000 // compiler-internal constant length limit
- testProg(dir, "x1", limit, true)
- testProg(dir, "x2", limit+1, false)
+ const bitLimit = 512
+ const charLimit = 10000 // compiler-internal constant length limit
+ testProg(dir, "x1", bitLimit, "")
+ testProg(dir, "x2", bitLimit+1, "constant overflow")
+ testProg(dir, "x3", charLimit-2, "constant overflow") // -2 because literal contains 0b prefix
+ testProg(dir, "x4", charLimit-1, "excessively long constant")
}
--- /dev/null
+// errorcheck
+
+// Copyright 2022 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.
+
+// Don't crash in export of oversized integer constant.
+
+package p
+
+const C = 912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912_345_678_901_234_567_890_123_456_789_012_345_678_901_234_567_890_912 // ERROR "constant overflow"