Skip to content

Commit 29c1d7c

Browse files
committed
compiler: fix incorrect unsafe.Alignof on some 32-bit architectures
This should fix #2643
1 parent ecb7eeb commit 29c1d7c

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

compiler/compiler.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,10 +234,15 @@ func Sizes(machine llvm.TargetMachine) types.Sizes {
234234
panic("unknown pointer size")
235235
}
236236

237+
// Construct a complex128 type because that's likely the type with the
238+
// biggest alignment on most/all ABIs.
239+
ctx := llvm.NewContext()
240+
defer ctx.Dispose()
241+
complex128Type := ctx.StructType([]llvm.Type{ctx.DoubleType(), ctx.DoubleType()}, false)
237242
return &stdSizes{
238243
IntSize: int64(intWidth / 8),
239244
PtrSize: int64(targetData.PointerSize()),
240-
MaxAlign: int64(targetData.PrefTypeAlignment(targetData.IntPtrType())),
245+
MaxAlign: int64(targetData.ABITypeAlignment(complex128Type)),
241246
}
242247
}
243248

testdata/reflect.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,19 @@ func main() {
170170
assertSize(reflect.TypeOf(new(int)).Size() == unsafe.Sizeof(new(int)), "*int")
171171
assertSize(reflect.TypeOf(zeroFunc).Size() == unsafe.Sizeof(zeroFunc), "func()")
172172

173+
// Test that offset is correctly calculated.
174+
// This doesn't just test reflect but also (indirectly) that unsafe.Alignof
175+
// works correctly.
176+
s := struct {
177+
small1 byte
178+
big1 int64
179+
small2 byte
180+
big2 int64
181+
}{}
182+
st := reflect.TypeOf(s)
183+
println("offset for int64 matches:", st.Field(1).Offset-st.Field(0).Offset == uintptr(unsafe.Pointer(&s.big1))-uintptr(unsafe.Pointer(&s.small1)))
184+
println("offset for complex128 matches:", st.Field(3).Offset-st.Field(2).Offset == uintptr(unsafe.Pointer(&s.big2))-uintptr(unsafe.Pointer(&s.small2)))
185+
173186
// SetBool
174187
rv := reflect.ValueOf(new(bool)).Elem()
175188
rv.SetBool(true)

testdata/reflect.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,8 @@ float32 4 32
401401
float64 8 64
402402
complex64 8 64
403403
complex128 16 128
404+
offset for int64 matches: true
405+
offset for complex128 matches: true
404406
type assertion succeeded for unreferenced type
405407

406408
struct tags

0 commit comments

Comments
 (0)