return len(fieldName) > 0
}
+// This must match cmd/compile/internal/compare.IsRegularMemory
+func isRegularMemory(t Type) bool {
+ switch t.Kind() {
+ case Array:
+ return isRegularMemory(t.Elem())
+ case Int8, Int16, Int32, Int64, Int, Uint8, Uint16, Uint32, Uint64, Uint, Uintptr, Chan, Pointer, Bool, UnsafePointer:
+ return true
+ case Struct:
+ num := t.NumField()
+ switch num {
+ case 0:
+ return true
+ case 1:
+ field := t.Field(0)
+ if field.Name == "_" {
+ return false
+ }
+ return isRegularMemory(field.Type)
+ default:
+ for i := range num {
+ field := t.Field(i)
+ if field.Name == "_" || !isRegularMemory(field.Type) || isPaddedField(t, i) {
+ return false
+ }
+ }
+ return true
+ }
+ }
+ return false
+}
+
+// isPaddedField reports whether the i'th field of struct type t is followed
+// by padding.
+func isPaddedField(t Type, i int) bool {
+ field := t.Field(i)
+ if i+1 < t.NumField() {
+ return field.Offset+field.Type.Size() != t.Field(i+1).Offset
+ }
+ return field.Offset+field.Type.Size() != t.Size()
+}
+
// StructOf returns the struct type containing fields.
// The Offset and Index fields are ignored and computed as they would be
// by the compiler.
}
typ.Str = resolveReflectName(newName(str, "", false, false))
- typ.TFlag = 0 // TODO: set tflagRegularMemory
+ if isRegularMemory(toType(&typ.Type)) {
+ typ.TFlag = abi.TFlagRegularMemory
+ } else {
+ typ.TFlag = 0
+ }
typ.Hash = hash
typ.Size_ = size
typ.PtrBytes = typeptrdata(&typ.Type)
_ = x.Name()
})
}
+
+func TestIsRegularMemory(t *testing.T) {
+ type args struct {
+ t reflect.Type
+ }
+ type S struct {
+ int
+ }
+ tests := []struct {
+ name string
+ args args
+ want bool
+ }{
+ {"struct{i int}", args{reflect.TypeOf(struct{ i int }{})}, true},
+ {"struct{}", args{reflect.TypeOf(struct{}{})}, true},
+ {"struct{i int; s S}", args{reflect.TypeOf(struct {
+ i int
+ s S
+ }{})}, true},
+ {"map[int][int]", args{reflect.TypeOf(map[int]int{})}, false},
+ {"[4]chan int", args{reflect.TypeOf([4]chan int{})}, true},
+ {"struct{i int; _ S}", args{reflect.TypeOf(struct {
+ i int
+ _ S
+ }{})}, false},
+ {"struct{a int16; b int32}", args{reflect.TypeOf(struct {
+ a int16
+ b int32
+ }{})}, false},
+ {"struct {x int32; y int16}", args{reflect.TypeOf(struct {
+ x int32
+ y int16
+ }{})}, false},
+ {"struct {_ int32 }", args{reflect.TypeOf(struct{ _ int32 }{})}, false},
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if got := reflect.IsRegularMemory(tt.args.t); got != tt.want {
+ t.Errorf("isRegularMemory() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}