зеркало из https://github.com/CryptoPro/go.git
cmd/compile: fix buglet in walk convert phase relating to convT64
The function runtime.convT64 accepts a single uint64 argument, but the compiler's rules in the walk phase for determining whether is it ok to pass a value of type T to a call to runtime.convT64 were slightly off. In particular the test was allowing a type T with size less than eight bytes but with more than one internal element (e.g. a struct). This patch tightens up the rules somewhat to prevent this from happening. Updates #40724. Change-Id: I3b909267534db59429b0aa73a3d73333e1bd6432 Reviewed-on: https://go-review.googlesource.com/c/go/+/308069 Trust: Than McIntosh <thanm@google.com> Run-TryBot: Than McIntosh <thanm@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
Родитель
d474b6c824
Коммит
ca8540affd
|
@ -14,6 +14,7 @@ import (
|
|||
"cmd/compile/internal/ssagen"
|
||||
"cmd/compile/internal/typecheck"
|
||||
"cmd/compile/internal/types"
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/sys"
|
||||
)
|
||||
|
||||
|
@ -316,6 +317,14 @@ func convFuncName(from, to *types.Type) (fnname string, needsaddr bool) {
|
|||
return false
|
||||
}
|
||||
|
||||
// Helper to determine whether a given type (when passed to a
|
||||
// function) will fit into a single integer register, assuming
|
||||
// that the reg abi is in effect. This is somewhat ad-hoc, there
|
||||
// may be a cleaner way to do this.
|
||||
fitsInSingleIntReg := func(t *types.Type) bool {
|
||||
return from.IsScalar() || types.IsDirectIface(from)
|
||||
}
|
||||
|
||||
tkind := to.Tie()
|
||||
switch from.Tie() {
|
||||
case 'I':
|
||||
|
@ -332,7 +341,7 @@ func convFuncName(from, to *types.Type) (fnname string, needsaddr bool) {
|
|||
return "convT32", false
|
||||
case from.Size() == 8 && isFloatLike(from):
|
||||
return "convT64F", false
|
||||
case from.Size() == 8 && from.Align == types.Types[types.TUINT64].Align && !from.HasPointers():
|
||||
case from.Size() == 8 && from.Align == types.Types[types.TUINT64].Align && !from.HasPointers() && (!objabi.Experiment.RegabiArgs || fitsInSingleIntReg(from)):
|
||||
return "convT64", false
|
||||
}
|
||||
if sc := from.SoleComponent(); sc != nil {
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
// 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.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type MyStruct struct {
|
||||
F0 [0]float64
|
||||
F1 byte
|
||||
F2 int16
|
||||
_ struct {
|
||||
F0 uint32
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
p0 := MyStruct{F0: [0]float64{}, F1: byte(27), F2: int16(9887)}
|
||||
fmt.Println(p0)
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
{[] 27 9887 {0}}
|
Загрузка…
Ссылка в новой задаче