import (
"reflect";
- "testing"
+ "testing";
+ "unsafe";
)
var doprint bool = false
t.Error("DeepEqual(complex different) = true, want false");
}
}
+
+
+func check2ndField(x interface{}, offs uintptr, t *testing.T) {
+ s := reflect.NewValue(x).(reflect.StructValue);
+ name, ftype, tag, reflect_offset := s.Type().(reflect.StructType).Field(1);
+ if uintptr(reflect_offset) != offs {
+ t.Error("mismatched offsets in structure alignment:", reflect_offset, offs);
+ }
+}
+
+// Check that structure alignment & offsets viewed through reflect agree with those
+// from the compiler itself.
+func TestAlignment(t *testing.T) {
+ type T1inner struct {
+ a int
+ }
+ type T1 struct {
+ T1inner;
+ f int;
+ }
+ type T2inner struct {
+ a, b int
+ }
+ type T2 struct {
+ T2inner;
+ f int;
+ }
+
+ x := T1{T1inner{2}, 17};
+ check2ndField(x, uintptr(unsafe.Pointer(&x.f)) - uintptr(unsafe.Pointer(&x)), t);
+
+ x1 := T2{T2inner{2, 3}, 17};
+ check2ndField(x1, uintptr(unsafe.Pointer(&x1.f)) - uintptr(unsafe.Pointer(&x1)), t);
+}
)
const (
- minStructAlign = unsafe.Sizeof(minStruct) - 1;
+ minStructAlignMask = unsafe.Sizeof(minStruct) - 1;
ptrsize = unsafe.Sizeof(&x);
interfacesize = unsafe.Sizeof(x.xinterface);
)
return t.size
}
size := 0;
- structalign := 0;
+ structAlignMask := 0;
for i := 0; i < len(t.field); i++ {
typ := t.field[i].typ.Get();
elemsize := typ.Size();
- align := typ.FieldAlign() - 1;
- if align > structalign {
- structalign = align
+ alignMask := typ.FieldAlign() - 1;
+ if alignMask > structAlignMask {
+ structAlignMask = alignMask
}
- if align > 0 {
- size = (size + align) &^ align;
+ if alignMask > 0 {
+ size = (size + alignMask) &^ alignMask;
}
t.field[i].offset = size;
size += elemsize;
}
- if (structalign > 0) {
+ if (structAlignMask > 0) {
// 6g etc. always aligns structs to a minimum size, typically int64
- if structalign < minStructAlign {
- structalign = minStructAlign
+ if structAlignMask < minStructAlignMask {
+ structAlignMask = minStructAlignMask
}
// TODO: In the PPC64 ELF ABI, floating point fields
// in a struct are aligned to a 4-byte boundary, but
// if the first field in the struct is a 64-bit float,
// the whole struct is aligned to an 8-byte boundary.
- size = (size + structalign) &^ structalign;
- t.fieldAlign = structalign + 1;
+ size = (size + structAlignMask) &^ structAlignMask;
+ t.fieldAlign = structAlignMask + 1;
}
t.size = size;
return size;