mirror of
https://github.com/golang/go
synced 2024-11-22 21:40:03 -07: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
@ -718,11 +718,14 @@ func square(x constant.Value) constant.Value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// For matching historical "constant OP overflow" error messages.
|
// For matching historical "constant OP overflow" error messages.
|
||||||
|
// TODO(mdempsky): Replace with error messages like go/types uses.
|
||||||
var overflowNames = [...]string{
|
var overflowNames = [...]string{
|
||||||
OADD: "addition",
|
OADD: "addition",
|
||||||
OSUB: "subtraction",
|
OSUB: "subtraction",
|
||||||
OMUL: "multiplication",
|
OMUL: "multiplication",
|
||||||
OLSH: "shift",
|
OLSH: "shift",
|
||||||
|
OXOR: "bitwise XOR",
|
||||||
|
OBITNOT: "bitwise complement",
|
||||||
}
|
}
|
||||||
|
|
||||||
// origConst returns an OLITERAL with orig n and value v.
|
// origConst returns an OLITERAL with orig n and value v.
|
||||||
@ -732,32 +735,24 @@ func origConst(n *Node, v constant.Value) *Node {
|
|||||||
lineno = lno
|
lineno = lno
|
||||||
|
|
||||||
switch v.Kind() {
|
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:
|
case constant.Int:
|
||||||
if constant.BitLen(v) > Mpprec {
|
if constant.BitLen(v) <= Mpprec {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
case constant.Unknown:
|
||||||
what := overflowNames[n.Op]
|
what := overflowNames[n.Op]
|
||||||
if what == "" {
|
if what == "" {
|
||||||
Fatalf("unexpected overflow: %v", n.Op)
|
Fatalf("unexpected overflow: %v", n.Op)
|
||||||
}
|
}
|
||||||
yyerror("constant %v overflow", what)
|
yyerrorl(n.Pos, "constant %v overflow", what)
|
||||||
n.Type = nil
|
n.Type = nil
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
orig := n
|
orig := n
|
||||||
n = nod(OLITERAL, nil, nil)
|
n = nodl(orig.Pos, OLITERAL, nil, nil)
|
||||||
n.Orig = orig
|
n.Orig = orig
|
||||||
n.Pos = orig.Pos
|
|
||||||
n.Type = orig.Type
|
n.Type = orig.Type
|
||||||
n.SetVal(v)
|
n.SetVal(v)
|
||||||
return n
|
return n
|
||||||
@ -800,8 +795,10 @@ func origIntConst(n *Node, v int64) *Node {
|
|||||||
// nodlit returns a new untyped constant with value v.
|
// nodlit returns a new untyped constant with value v.
|
||||||
func nodlit(v constant.Value) *Node {
|
func nodlit(v constant.Value) *Node {
|
||||||
n := nod(OLITERAL, nil, nil)
|
n := nod(OLITERAL, nil, nil)
|
||||||
n.Type = idealType(v.Kind())
|
if k := v.Kind(); k != constant.Unknown {
|
||||||
|
n.Type = idealType(k)
|
||||||
n.SetVal(v)
|
n.SetVal(v)
|
||||||
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,3 +19,14 @@ const LargeB = LargeA * LargeA * LargeA
|
|||||||
const LargeC = LargeB * LargeB * LargeB // GC_ERROR "constant multiplication overflow"
|
const LargeC = LargeB * LargeB * LargeB // GC_ERROR "constant multiplication overflow"
|
||||||
|
|
||||||
const AlsoLargeA = LargeA << 400 << 400 >> 400 >> 400 // GC_ERROR "constant shift 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
|
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
|
const _ = 1e+1000000000 // ERROR "malformed constant: 1e\+1000000000"
|
||||||
|
Loading…
Reference in New Issue
Block a user