diff --git a/src/cmd/compile/internal/walk/convert.go b/src/cmd/compile/internal/walk/convert.go index 3d30aefd5f..547e08dcab 100644 --- a/src/cmd/compile/internal/walk/convert.go +++ b/src/cmd/compile/internal/walk/convert.go @@ -312,7 +312,22 @@ func convFuncName(from, to *types.Type) (fnname string, needsaddr bool) { case types.TARRAY: return t.NumElem() == 1 && isFloatLike(t.Elem()) case types.TSTRUCT: - return t.NumFields() == 1 && isFloatLike(t.Field(0).Type) + // 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 { + continue + } + if isFloatLike(f.Type) && idx == len(fsl)-1 { + return true + } + return false + } + return false } return false } diff --git a/test/abi/convF_criteria.go b/test/abi/convF_criteria.go new file mode 100644 index 0000000000..77ed56d4a4 --- /dev/null +++ b/test/abi/convF_criteria.go @@ -0,0 +1,27 @@ +// 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]struct{} + F1 float32 +} + +type myStruct2 struct { + F0 [0]struct{} + F1 float32 + F2 [0]struct{} +} + +func main() { + x := myStruct{F1: -1.25} + fmt.Println(x) + x2 := myStruct2{F1: -7.97} + fmt.Println(x2) +} diff --git a/test/abi/convF_criteria.out b/test/abi/convF_criteria.out new file mode 100644 index 0000000000..457f0defc9 --- /dev/null +++ b/test/abi/convF_criteria.out @@ -0,0 +1,2 @@ +{[] -1.25} +{[] -7.97 []}