Source file
src/go/types/sizes_test.go
1
2
3
4
5
6
7 package types_test
8
9 import (
10 "go/ast"
11 "go/token"
12 "go/types"
13 "internal/testenv"
14 "testing"
15 )
16
17
18 func findStructType(t *testing.T, src string) *types.Struct {
19 return findStructTypeConfig(t, src, &types.Config{})
20 }
21
22 func findStructTypeConfig(t *testing.T, src string, conf *types.Config) *types.Struct {
23 types_ := make(map[ast.Expr]types.TypeAndValue)
24 mustTypecheck(src, nil, &types.Info{Types: types_})
25 for _, tv := range types_ {
26 if ts, ok := tv.Type.(*types.Struct); ok {
27 return ts
28 }
29 }
30 t.Fatalf("failed to find a struct type in src:\n%s\n", src)
31 return nil
32 }
33
34
35 func TestMultipleSizeUse(t *testing.T) {
36 const src = `
37 package main
38
39 type S struct {
40 i int
41 b bool
42 s string
43 n int
44 }
45 `
46 ts := findStructType(t, src)
47 sizes := types.StdSizes{WordSize: 4, MaxAlign: 4}
48 if got := sizes.Sizeof(ts); got != 20 {
49 t.Errorf("Sizeof(%v) with WordSize 4 = %d want 20", ts, got)
50 }
51 sizes = types.StdSizes{WordSize: 8, MaxAlign: 8}
52 if got := sizes.Sizeof(ts); got != 40 {
53 t.Errorf("Sizeof(%v) with WordSize 8 = %d want 40", ts, got)
54 }
55 }
56
57
58 func TestAlignofNaclSlice(t *testing.T) {
59 const src = `
60 package main
61
62 var s struct {
63 x *int
64 y []byte
65 }
66 `
67 ts := findStructType(t, src)
68 sizes := &types.StdSizes{WordSize: 4, MaxAlign: 8}
69 var fields []*types.Var
70
71 for i := 0; i < ts.NumFields(); i++ {
72 fields = append(fields, ts.Field(i))
73 }
74 offsets := sizes.Offsetsof(fields)
75 if offsets[0] != 0 || offsets[1] != 4 {
76 t.Errorf("OffsetsOf(%v) = %v want %v", ts, offsets, []int{0, 4})
77 }
78 }
79
80 func TestIssue16902(t *testing.T) {
81 const src = `
82 package a
83
84 import "unsafe"
85
86 const _ = unsafe.Offsetof(struct{ x int64 }{}.x)
87 `
88 info := types.Info{Types: make(map[ast.Expr]types.TypeAndValue)}
89 conf := types.Config{
90
91 Importer: defaultImporter(token.NewFileSet()),
92 Sizes: &types.StdSizes{WordSize: 8, MaxAlign: 8},
93 }
94 mustTypecheck(src, &conf, &info)
95 for _, tv := range info.Types {
96 _ = conf.Sizes.Sizeof(tv.Type)
97 _ = conf.Sizes.Alignof(tv.Type)
98 }
99 }
100
101
102 func TestAtomicAlign(t *testing.T) {
103 testenv.MustHaveGoBuild(t)
104
105 const src = `
106 package main
107
108 import "sync/atomic"
109
110 var s struct {
111 x int32
112 y atomic.Int64
113 z int64
114 }
115 `
116
117 want := []int64{0, 8, 16}
118 for _, arch := range []string{"386", "amd64"} {
119 t.Run(arch, func(t *testing.T) {
120 conf := types.Config{
121
122 Importer: defaultImporter(token.NewFileSet()),
123 Sizes: types.SizesFor("gc", arch),
124 }
125 ts := findStructTypeConfig(t, src, &conf)
126 var fields []*types.Var
127
128 for i := 0; i < ts.NumFields(); i++ {
129 fields = append(fields, ts.Field(i))
130 }
131
132 offsets := conf.Sizes.Offsetsof(fields)
133 if offsets[0] != want[0] || offsets[1] != want[1] || offsets[2] != want[2] {
134 t.Errorf("OffsetsOf(%v) = %v want %v", ts, offsets, want)
135 }
136 })
137 }
138 }
139
140 type gcSizeTest struct {
141 name string
142 src string
143 }
144
145 var gcSizesTests = []gcSizeTest{
146 {
147 "issue60431",
148 `
149 package main
150
151 import "unsafe"
152
153 // The foo struct size is expected to be rounded up to 16 bytes.
154 type foo struct {
155 a int64
156 b bool
157 }
158
159 func main() {
160 assert(unsafe.Sizeof(foo{}) == 16)
161 }`,
162 },
163 {
164 "issue60734",
165 `
166 package main
167
168 import (
169 "unsafe"
170 )
171
172 // The Data struct size is expected to be rounded up to 16 bytes.
173 type Data struct {
174 Value uint32 // 4 bytes
175 Label [10]byte // 10 bytes
176 Active bool // 1 byte
177 // padded with 1 byte to make it align
178 }
179
180 func main() {
181 assert(unsafe.Sizeof(Data{}) == 16)
182 }
183 `,
184 },
185 }
186
187 func TestGCSizes(t *testing.T) {
188 types.DefPredeclaredTestFuncs()
189 for _, tc := range gcSizesTests {
190 tc := tc
191 t.Run(tc.name, func(t *testing.T) {
192 t.Parallel()
193 conf := types.Config{
194
195 Importer: defaultImporter(token.NewFileSet()),
196 Sizes: types.SizesFor("gc", "amd64"),
197 }
198 mustTypecheck(tc.src, &conf, nil)
199 })
200 }
201 }
202
View as plain text