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