mirror of
https://github.com/golang/go
synced 2024-11-02 13:42:29 +00:00
[dev.regabi] cmd/compile: fix reporting of overflow
In the previous CL, I had incorrectly removed one of the error messages from issue20232.go, because I thought go/constant was just handling it. But actually the compiler was panicking in nodlit, because it didn't handle constant.Unknown. So this CL makes it leave n.Type == nil for unknown constant.Values. While here, also address #42732 by making sure to report an error message when origConst is called with an unknown constant.Value (as can happen when multiplying two floating-point constants overflows). Finally, add OXOR and OBITNOT to the list of operations to report errors about, since they're also constant expressions that can produce a constant with a greater bit length than their operands. Fixes #42732. Change-Id: I4a538fbae9b3ac4c553d7de5625dc0c87d9acce3 Reviewed-on: https://go-review.googlesource.com/c/go/+/272928 Trust: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
18573aea3c
commit
259fd8adbb
3 changed files with 36 additions and 27 deletions
|
@ -718,11 +718,14 @@ func square(x constant.Value) constant.Value {
|
|||
}
|
||||
|
||||
// For matching historical "constant OP overflow" error messages.
|
||||
// TODO(mdempsky): Replace with error messages like go/types uses.
|
||||
var overflowNames = [...]string{
|
||||
OADD: "addition",
|
||||
OSUB: "subtraction",
|
||||
OMUL: "multiplication",
|
||||
OLSH: "shift",
|
||||
OXOR: "bitwise XOR",
|
||||
OBITNOT: "bitwise complement",
|
||||
}
|
||||
|
||||
// origConst returns an OLITERAL with orig n and value v.
|
||||
|
@ -732,32 +735,24 @@ func origConst(n *Node, v constant.Value) *Node {
|
|||
lineno = lno
|
||||
|
||||
switch v.Kind() {
|
||||
case constant.Unknown:
|
||||
// If constant folding was attempted (we were called)
|
||||
// but it produced an invalid constant value,
|
||||
// mark n as broken and give up.
|
||||
if Errors() == 0 {
|
||||
Fatalf("should have reported an error")
|
||||
}
|
||||
n.Type = nil
|
||||
return n
|
||||
|
||||
case constant.Int:
|
||||
if constant.BitLen(v) > Mpprec {
|
||||
if constant.BitLen(v) <= Mpprec {
|
||||
break
|
||||
}
|
||||
fallthrough
|
||||
case constant.Unknown:
|
||||
what := overflowNames[n.Op]
|
||||
if what == "" {
|
||||
Fatalf("unexpected overflow: %v", n.Op)
|
||||
}
|
||||
yyerror("constant %v overflow", what)
|
||||
yyerrorl(n.Pos, "constant %v overflow", what)
|
||||
n.Type = nil
|
||||
return n
|
||||
}
|
||||
}
|
||||
|
||||
orig := n
|
||||
n = nod(OLITERAL, nil, nil)
|
||||
n = nodl(orig.Pos, OLITERAL, nil, nil)
|
||||
n.Orig = orig
|
||||
n.Pos = orig.Pos
|
||||
n.Type = orig.Type
|
||||
n.SetVal(v)
|
||||
return n
|
||||
|
@ -800,8 +795,10 @@ func origIntConst(n *Node, v int64) *Node {
|
|||
// nodlit returns a new untyped constant with value v.
|
||||
func nodlit(v constant.Value) *Node {
|
||||
n := nod(OLITERAL, nil, nil)
|
||||
n.Type = idealType(v.Kind())
|
||||
if k := v.Kind(); k != constant.Unknown {
|
||||
n.Type = idealType(k)
|
||||
n.SetVal(v)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
|
|
|
@ -19,3 +19,14 @@ const LargeB = LargeA * LargeA * LargeA
|
|||
const LargeC = LargeB * LargeB * LargeB // GC_ERROR "constant multiplication overflow"
|
||||
|
||||
const AlsoLargeA = LargeA << 400 << 400 >> 400 >> 400 // GC_ERROR "constant shift overflow"
|
||||
|
||||
// Issue #42732.
|
||||
|
||||
const a = 1e+500000000
|
||||
const b = a * a // ERROR "constant multiplication overflow"
|
||||
const c = b * b
|
||||
|
||||
const MaxInt512 = (1<<256 - 1) * (1<<256 + 1)
|
||||
const _ = MaxInt512 + 1 // ERROR "constant addition overflow"
|
||||
const _ = MaxInt512 ^ -1 // ERROR "constant bitwise XOR overflow"
|
||||
const _ = ^MaxInt512 // ERROR "constant bitwise complement overflow"
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
package main
|
||||
|
||||
const _ = 6e5518446744 // ERROR "malformed constant: 6e5518446744"
|
||||
const x = 6e5518446744 // ERROR "malformed constant: 6e5518446744"
|
||||
const _ = x * x
|
||||
const _ = 1e-1000000000
|
||||
const _ = 1e+1000000000
|
||||
const _ = 1e+1000000000 // ERROR "malformed constant: 1e\+1000000000"
|
||||
|
|
Loading…
Reference in a new issue