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/importer"
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 Importer: importer.Default(),
91 Sizes: &types.StdSizes{WordSize: 8, MaxAlign: 8},
92 }
93 mustTypecheck(src, &conf, &info)
94 for _, tv := range info.Types {
95 _ = conf.Sizes.Sizeof(tv.Type)
96 _ = conf.Sizes.Alignof(tv.Type)
97 }
98 }
99
100
101 func TestAtomicAlign(t *testing.T) {
102 testenv.MustHaveGoBuild(t)
103
104 const src = `
105 package main
106
107 import "sync/atomic"
108
109 var s struct {
110 x int32
111 y atomic.Int64
112 z int64
113 }
114 `
115
116 want := []int64{0, 8, 16}
117 for _, arch := range []string{"386", "amd64"} {
118 t.Run(arch, func(t *testing.T) {
119 conf := types.Config{
120 Importer: importer.Default(),
121 Sizes: types.SizesFor("gc", arch),
122 }
123 ts := findStructTypeConfig(t, src, &conf)
124 var fields []*types.Var
125
126 for i := 0; i < ts.NumFields(); i++ {
127 fields = append(fields, ts.Field(i))
128 }
129
130 offsets := conf.Sizes.Offsetsof(fields)
131 if offsets[0] != want[0] || offsets[1] != want[1] || offsets[2] != want[2] {
132 t.Errorf("OffsetsOf(%v) = %v want %v", ts, offsets, want)
133 }
134 })
135 }
136 }
137
138 type gcSizeTest struct {
139 name string
140 src string
141 }
142
143 var gcSizesTests = []gcSizeTest{
144 {
145 "issue60431",
146 `
147 package main
148
149 import "unsafe"
150
151 // The foo struct size is expected to be rounded up to 16 bytes.
152 type foo struct {
153 a int64
154 b bool
155 }
156
157 func main() {
158 assert(unsafe.Sizeof(foo{}) == 16)
159 }`,
160 },
161 {
162 "issue60734",
163 `
164 package main
165
166 import (
167 "unsafe"
168 )
169
170 // The Data struct size is expected to be rounded up to 16 bytes.
171 type Data struct {
172 Value uint32 // 4 bytes
173 Label [10]byte // 10 bytes
174 Active bool // 1 byte
175 // padded with 1 byte to make it align
176 }
177
178 func main() {
179 assert(unsafe.Sizeof(Data{}) == 16)
180 }
181 `,
182 },
183 }
184
185 func TestGCSizes(t *testing.T) {
186 types.DefPredeclaredTestFuncs()
187 for _, tc := range gcSizesTests {
188 tc := tc
189 t.Run(tc.name, func(t *testing.T) {
190 t.Parallel()
191 conf := types.Config{Importer: importer.Default(), Sizes: types.SizesFor("gc", "amd64")}
192 mustTypecheck(tc.src, &conf, nil)
193 })
194 }
195 }
196
View as plain text