0
1
mirror of https://github.com/golang/go synced 2024-11-11 12:49:30 +00:00
go/test/abi/idata.go
David Chase ee40bb666b cmd/compile: add "surprised by IData of Arg" case for register args
This fixes a compile crash for
GOEXPERIMENT=regabi,regabiargs go test -c  go/constant

Updates #40724.

Change-Id: I238cef436e045647815326fc8fdb025c30ba1f5c
Reviewed-on: https://go-review.googlesource.com/c/go/+/307309
Trust: David Chase <drchase@google.com>
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
2021-04-05 20:11:08 +00:00

98 lines
2.1 KiB
Go

// 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.
// Excerpted from go/constant/value.go to capture a bug from there.
package main
import (
"fmt"
"math"
"math/big"
)
type (
unknownVal struct{}
intVal struct{ val *big.Int } // Int values not representable as an int64
ratVal struct{ val *big.Rat } // Float values representable as a fraction
floatVal struct{ val *big.Float } // Float values not representable as a fraction
complexVal struct{ re, im Value }
)
const prec = 512
func (unknownVal) String() string { return "unknown" }
func (x intVal) String() string { return x.val.String() }
func (x ratVal) String() string { return rtof(x).String() }
func (x floatVal) String() string {
f := x.val
// Use exact fmt formatting if in float64 range (common case):
// proceed if f doesn't underflow to 0 or overflow to inf.
if x, _ := f.Float64(); f.Sign() == 0 == (x == 0) && !math.IsInf(x, 0) {
return fmt.Sprintf("%.6g", x)
}
return "OOPS"
}
func (x complexVal) String() string { return fmt.Sprintf("(%s + %si)", x.re, x.im) }
func newFloat() *big.Float { return new(big.Float).SetPrec(prec) }
//go:noinline
//go:registerparams
func itor(x intVal) ratVal { return ratVal{nil} }
//go:noinline
//go:registerparams
func itof(x intVal) floatVal { return floatVal{nil} }
func rtof(x ratVal) floatVal { return floatVal{newFloat().SetRat(x.val)} }
type Value interface {
String() string
}
//go:noinline
//go:registerparams
func ToFloat(x Value) Value {
switch x := x.(type) {
case intVal:
if smallInt(x.val) {
return itor(x)
}
return itof(x)
case ratVal, floatVal:
return x
case complexVal:
if Sign(x.im) == 0 {
return ToFloat(x.re)
}
}
return unknownVal{}
}
//go:noinline
//go:registerparams
func smallInt(x *big.Int) bool {
return false
}
//go:noinline
//go:registerparams
func Sign(x Value) int {
return 0
}
func main() {
v := ratVal{big.NewRat(22,7)}
s := ToFloat(v).String()
fmt.Printf("s=%s\n", s)
}