mirror of
https://github.com/golang/go
synced 2024-11-12 02:40:21 -07:00
cmd/compile: reject large floating point exponents without math/big
For #11326 (but not a fix). Change-Id: Ic51814f5cd7357427c3fd990a5522775d05e7987 Reviewed-on: https://go-review.googlesource.com/11673 Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
643ef15b16
commit
1122836b5f
@ -9,6 +9,7 @@ import (
|
||||
"cmd/internal/obj"
|
||||
"fmt"
|
||||
"math"
|
||||
"strings"
|
||||
)
|
||||
|
||||
/// implements float arihmetic
|
||||
@ -153,6 +154,30 @@ func mpatoflt(a *Mpflt, as string) {
|
||||
as = as[1:]
|
||||
}
|
||||
|
||||
// The spec requires accepting exponents that fit in int32.
|
||||
// Don't accept much more than that.
|
||||
// Count digits in exponent and stop early if there are too many.
|
||||
if i := strings.Index(as, "e"); i >= 0 {
|
||||
i++
|
||||
if i < len(as) && (as[i] == '-' || as[i] == '+') {
|
||||
i++
|
||||
}
|
||||
for i < len(as) && as[i] == '0' {
|
||||
i++
|
||||
}
|
||||
// TODO(rsc): This should be > 10, because we're supposed
|
||||
// to accept any signed 32-bit int as an exponent.
|
||||
// But that's not working terribly well, so we deviate from the
|
||||
// spec in order to make sure that what we accept works.
|
||||
// We can remove this restriction once those larger exponents work.
|
||||
// See golang.org/issue/11326 and test/fixedbugs/issue11326*.go.
|
||||
if len(as)-i > 8 {
|
||||
Yyerror("malformed constant: %s (exponent too large)", as)
|
||||
a.Val.SetUint64(0)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
f, ok := a.Val.SetString(as)
|
||||
if !ok {
|
||||
// At the moment we lose precise error cause;
|
||||
@ -164,11 +189,13 @@ func mpatoflt(a *Mpflt, as string) {
|
||||
// TODO(gri) use different conversion function or check separately
|
||||
Yyerror("malformed constant: %s", as)
|
||||
a.Val.SetUint64(0)
|
||||
return
|
||||
}
|
||||
|
||||
if f.IsInf() {
|
||||
Yyerror("constant too large: %s", as)
|
||||
a.Val.SetUint64(0)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,10 +144,12 @@ func TestStdFixed(t *testing.T) {
|
||||
|
||||
testTestDir(t, filepath.Join(runtime.GOROOT(), "test", "fixedbugs"),
|
||||
"bug248.go", "bug302.go", "bug369.go", // complex test instructions - ignore
|
||||
"bug459.go", // possibly incorrect test - see issue 6703 (pending spec clarification)
|
||||
"issue3924.go", // possibly incorrect test - see issue 6671 (pending spec clarification)
|
||||
"issue6889.go", // gc-specific test
|
||||
"issue7746.go", // large constants - consumes too much memory
|
||||
"bug459.go", // possibly incorrect test - see issue 6703 (pending spec clarification)
|
||||
"issue3924.go", // possibly incorrect test - see issue 6671 (pending spec clarification)
|
||||
"issue6889.go", // gc-specific test
|
||||
"issue7746.go", // large constants - consumes too much memory
|
||||
"issue11326.go", // large constants
|
||||
"issue11326b.go", // large constants
|
||||
)
|
||||
}
|
||||
|
||||
|
28
test/fixedbugs/issue11326.go
Normal file
28
test/fixedbugs/issue11326.go
Normal file
@ -0,0 +1,28 @@
|
||||
// errorcheck
|
||||
|
||||
// Copyright 2015 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 main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
var g = 1e81391777742999 // ERROR "exponent too large"
|
||||
// The next should only cause a problem when converted to float64
|
||||
// by the assignment, but instead the compiler rejects it outright,
|
||||
// rather than mishandle it. Specifically, when handled, 'var h' prints:
|
||||
// issue11326.go:N: constant 0.93342e+536870911 overflows float64
|
||||
// The rejection of 'var i' is just insurance. It seems to work correctly.
|
||||
// See golang.org/issue/11326.
|
||||
// var h = 1e2147483647 // should be "1.00000e+2147483647 overflows float64"
|
||||
var h = 1e2147483647 // ERROR "exponent too large"
|
||||
// var i = 1e214748364 // should be "1.00000e\+214748364 overflows float64"
|
||||
var i = 1e214748364 // ERROR "exponent too large"
|
||||
var j = 1e21474836 // ERROR "1.00000e\+21474836 overflows float64"
|
||||
var k = 1e2147483 // ERROR "1.00000e\+2147483 overflows float64"
|
||||
var l = 1e214748 // ERROR "1.00000e\+214748 overflows float64"
|
||||
var m = 1e21474 // ERROR "1.00000e\+21474 overflows float64"
|
||||
fmt.Println(g)
|
||||
}
|
44
test/fixedbugs/issue11326b.go
Normal file
44
test/fixedbugs/issue11326b.go
Normal file
@ -0,0 +1,44 @@
|
||||
// run
|
||||
|
||||
// Copyright 2015 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 main
|
||||
|
||||
func main() {
|
||||
/* TODO(rsc): Should work but does not. See golang.org/issue/11326.
|
||||
{
|
||||
const n = 1e2147483647
|
||||
const d = 1e2147483646
|
||||
x := n / d
|
||||
if x != 10.0 {
|
||||
println("incorrect value:", x)
|
||||
}
|
||||
}
|
||||
{
|
||||
const n = 1e214748364
|
||||
const d = 1e214748363
|
||||
x := n / d
|
||||
if x != 10.0 {
|
||||
println("incorrect value:", x)
|
||||
}
|
||||
}
|
||||
*/
|
||||
{
|
||||
const n = 1e21474836
|
||||
const d = 1e21474835
|
||||
x := n / d
|
||||
if x != 10.0 {
|
||||
println("incorrect value:", x)
|
||||
}
|
||||
}
|
||||
{
|
||||
const n = 1e2147483
|
||||
const d = 1e2147482
|
||||
x := n / d
|
||||
if x != 10.0 {
|
||||
println("incorrect value:", x)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user