1// run -gcflags=-G=3
2
3// Copyright 2021 The Go Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7package main
8
9import (
10	"fmt"
11	"unsafe"
12)
13
14// size returns the size of type T
15func size[T any](x T) uintptr {
16	return unsafe.Sizeof(x)
17}
18
19// size returns the alignment of type T
20func align[T any](x T) uintptr {
21	return unsafe.Alignof(x)
22}
23
24type Tstruct[T any] struct {
25	f1 T
26	f2 int
27}
28
29// offset returns the offset of field f2 in the generic type Tstruct
30func (r *Tstruct[T]) offset() uintptr {
31	return unsafe.Offsetof(r.f2)
32}
33
34func main() {
35	v1 := int(5)
36	if got, want := size(v1), unsafe.Sizeof(v1); got != want {
37		panic(fmt.Sprintf("got %d, want %d", got, want))
38	}
39	if got, want := align(v1), unsafe.Alignof(v1); got != want {
40		panic(fmt.Sprintf("got %d, want %d", got, want))
41	}
42
43	v2 := "abc"
44	if got, want := size(v2), unsafe.Sizeof(v2); got != want {
45		panic(fmt.Sprintf("got %d, want %d", got, want))
46	}
47	if got, want := align(v2), unsafe.Alignof(v2); got != want {
48		panic(fmt.Sprintf("got %d, want %d", got, want))
49	}
50
51	var v3 Tstruct[int]
52	if got, want := unsafe.Offsetof(v3.f2), unsafe.Sizeof(v1); got != want {
53		panic(fmt.Sprintf("got %d, want %d", got, want))
54	}
55
56	var v4 Tstruct[interface{}]
57	var v5 interface{}
58	if got, want := unsafe.Offsetof(v4.f2), unsafe.Sizeof(v5); got != want {
59		panic(fmt.Sprintf("got %d, want %d", got, want))
60	}
61
62	if got, want := v3.offset(), unsafe.Offsetof(v3.f2); got != want {
63		panic(fmt.Sprintf("got %d, want %d", got, want))
64	}
65	if got, want := v4.offset(), unsafe.Offsetof(v4.f2); got != want {
66		panic(fmt.Sprintf("got %d, want %d", got, want))
67	}
68}
69