mirror of
https://github.com/golang/go
synced 2024-11-26 11:58:07 -07:00
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>
This commit is contained in:
parent
254fb85c12
commit
ee40bb666b
@ -317,6 +317,15 @@ func (x *expandState) rewriteSelect(leaf *Value, selector *Value, offset int64,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch selector.Op {
|
switch selector.Op {
|
||||||
|
case OpArgIntReg, OpArgFloatReg:
|
||||||
|
if leafType == selector.Type { // OpIData leads us here, sometimes.
|
||||||
|
leaf.copyOf(selector)
|
||||||
|
} else {
|
||||||
|
x.f.Fatalf("Unexpected %s type, selector=%s, leaf=%s\n", selector.Op.String(), selector.LongString(), leaf.LongString())
|
||||||
|
}
|
||||||
|
if x.debug {
|
||||||
|
x.Printf("---%s, break\n", selector.Op.String())
|
||||||
|
}
|
||||||
case OpArg:
|
case OpArg:
|
||||||
if !x.isAlreadyExpandedAggregateType(selector.Type) {
|
if !x.isAlreadyExpandedAggregateType(selector.Type) {
|
||||||
if leafType == selector.Type { // OpIData leads us here, sometimes.
|
if leafType == selector.Type { // OpIData leads us here, sometimes.
|
||||||
|
97
test/abi/idata.go
Normal file
97
test/abi/idata.go
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
// 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)
|
||||||
|
}
|
1
test/abi/idata.out
Normal file
1
test/abi/idata.out
Normal file
@ -0,0 +1 @@
|
|||||||
|
s=3.14286
|
Loading…
Reference in New Issue
Block a user