]> Cypherpunks.ru repositories - gostls13.git/blob - test/abi/idata.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / test / abi / idata.go
1 // run
2
3 // Copyright 2021 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
6
7 // Excerpted from go/constant/value.go to capture a bug from there.
8
9 package main
10
11 import (
12         "fmt"
13         "math"
14         "math/big"
15 )
16
17 type (
18         unknownVal struct{}
19         intVal     struct{ val *big.Int }   // Int values not representable as an int64
20         ratVal     struct{ val *big.Rat }   // Float values representable as a fraction
21         floatVal   struct{ val *big.Float } // Float values not representable as a fraction
22         complexVal struct{ re, im Value }
23 )
24
25 const prec = 512
26
27 func (unknownVal) String() string { return "unknown" }
28
29 func (x intVal) String() string   { return x.val.String() }
30 func (x ratVal) String() string   { return rtof(x).String() }
31
32 func (x floatVal) String() string {
33         f := x.val
34
35         // Use exact fmt formatting if in float64 range (common case):
36         // proceed if f doesn't underflow to 0 or overflow to inf.
37         if x, _ := f.Float64(); f.Sign() == 0 == (x == 0) && !math.IsInf(x, 0) {
38                 return fmt.Sprintf("%.6g", x)
39         }
40
41         return "OOPS"
42 }
43
44 func (x complexVal) String() string { return fmt.Sprintf("(%s + %si)", x.re, x.im) }
45
46 func newFloat() *big.Float { return new(big.Float).SetPrec(prec) }
47
48 //go:noinline
49 //go:registerparams
50 func itor(x intVal) ratVal       { return ratVal{nil} }
51
52 //go:noinline
53 //go:registerparams
54 func itof(x intVal) floatVal     { return floatVal{nil} }
55 func rtof(x ratVal) floatVal     { return floatVal{newFloat().SetRat(x.val)} }
56
57 type Value interface {
58         String() string
59 }
60
61 //go:noinline
62 //go:registerparams
63 func ToFloat(x Value) Value {
64         switch x := x.(type) {
65         case intVal:
66                 if smallInt(x.val) {
67                         return itor(x)
68                 }
69                 return itof(x)
70         case ratVal, floatVal:
71                 return x
72         case complexVal:
73                 if Sign(x.im) == 0 {
74                         return ToFloat(x.re)
75                 }
76         }
77         return unknownVal{}
78 }
79
80 //go:noinline
81 //go:registerparams
82 func smallInt(x *big.Int) bool {
83         return false
84 }
85
86 //go:noinline
87 //go:registerparams
88 func Sign(x Value) int {
89         return 0
90 }
91
92
93 func main() {
94         v := ratVal{big.NewRat(22,7)}
95         s := ToFloat(v).String()
96         fmt.Printf("s=%s\n", s)
97 }