1
0
mirror of https://github.com/golang/go synced 2024-11-26 07:27:59 -07:00

cmd/compile: adjust interface conversion function selection with 0-sized fields

0-sized fields do not affect how arguments are passed under the
register ABI. But it does affect the size and alignment of the
type, and may affect the choice of interface conversion function.
Specifically, struct { a [0]int32; b [4]byte } should be passed in
memory, therefore should not use convT32.

Change-Id: Idfa21af79b81c196b50253b0be1fa4edecd12b45
Reviewed-on: https://go-review.googlesource.com/c/go/+/308651
Trust: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
Cherry Zhang 2021-04-08 15:24:08 -04:00
parent 6c98ecda10
commit ec367e5b05

View File

@ -312,11 +312,6 @@ func convFuncName(from, to *types.Type) (fnname string, needsaddr bool) {
case types.TARRAY:
return t.NumElem() == 1 && isFloatLike(t.Elem())
case types.TSTRUCT:
// allow for the possibility that we have a series of
// leading fields that are zero size before a float field.
// in addition, if we find a float field, it needs to be
// the last item in the struct (a trailing zero length
// field would introduce padding).
fsl := t.FieldSlice()
for idx, f := range fsl {
if f.Type.Width == 0 {
@ -332,14 +327,6 @@ 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':
@ -352,11 +339,11 @@ func convFuncName(from, to *types.Type) (fnname string, needsaddr bool) {
return "convT16", false
case from.Size() == 4 && isFloatLike(from):
return "convT32F", false
case from.Size() == 4 && from.Align == 4 && !from.HasPointers():
case from.Size() == 4 && from.Align == 4 && !from.HasPointers() && (!objabi.Experiment.RegabiArgs || from.NumComponents(types.CountBlankFields) == 1):
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() && (!objabi.Experiment.RegabiArgs || fitsInSingleIntReg(from)):
case from.Size() == 8 && from.Align == types.Types[types.TUINT64].Align && !from.HasPointers() && (!objabi.Experiment.RegabiArgs || from.NumComponents(types.CountBlankFields) == 1):
return "convT64", false
}
if sc := from.SoleComponent(); sc != nil {