1// run
2//go:build !gcflags_noopt
3
4// Copyright 2010 The Go Authors. All rights reserved.
5// Use of this source code is governed by a BSD-style
6// license that can be found in the LICENSE file.
7
8// Test that many initializations can be done at link time and
9// generate no executable init functions.
10// Also test that trivial func init are optimized away.
11
12package main
13
14import (
15	"errors"
16	"unsafe"
17)
18
19// All these initializations should be done at link time.
20
21type S struct{ a, b, c int }
22type SS struct{ aa, bb, cc S }
23type SA struct{ a, b, c [3]int }
24type SC struct{ a, b, c []int }
25
26var (
27	zero                      = 2
28	one                       = 1
29	pi                        = 3.14
30	slice                     = []byte{1, 2, 3}
31	sliceInt                  = []int{1, 2, 3}
32	hello                     = "hello, world"
33	bytes                     = []byte("hello, world")
34	four, five                = 4, 5
35	x, y                      = 0.1, "hello"
36	nilslice   []byte         = nil
37	nilmap     map[string]int = nil
38	nilfunc    func()         = nil
39	nilchan    chan int       = nil
40	nilptr     *byte          = nil
41)
42
43var a = [3]int{1001, 1002, 1003}
44var s = S{1101, 1102, 1103}
45var c = []int{1201, 1202, 1203}
46
47var aa = [3][3]int{[3]int{2001, 2002, 2003}, [3]int{2004, 2005, 2006}, [3]int{2007, 2008, 2009}}
48var as = [3]S{S{2101, 2102, 2103}, S{2104, 2105, 2106}, S{2107, 2108, 2109}}
49
50var sa = SA{[3]int{3001, 3002, 3003}, [3]int{3004, 3005, 3006}, [3]int{3007, 3008, 3009}}
51var ss = SS{S{3101, 3102, 3103}, S{3104, 3105, 3106}, S{3107, 3108, 3109}}
52
53var ca = [][3]int{[3]int{4001, 4002, 4003}, [3]int{4004, 4005, 4006}, [3]int{4007, 4008, 4009}}
54var cs = []S{S{4101, 4102, 4103}, S{4104, 4105, 4106}, S{4107, 4108, 4109}}
55
56var answers = [...]int{
57	// s
58	1101, 1102, 1103,
59
60	// ss
61	3101, 3102, 3103,
62	3104, 3105, 3106,
63	3107, 3108, 3109,
64
65	// [0]
66	1001, 1201, 1301,
67	2101, 2102, 2103,
68	4101, 4102, 4103,
69	5101, 5102, 5103,
70	3001, 3004, 3007,
71	3201, 3204, 3207,
72	3301, 3304, 3307,
73
74	// [0][j]
75	2001, 2201, 2301, 4001, 4201, 4301, 5001, 5201, 5301,
76	2002, 2202, 2302, 4002, 4202, 4302, 5002, 5202, 5302,
77	2003, 2203, 2303, 4003, 4203, 4303, 5003, 5203, 5303,
78
79	// [1]
80	1002, 1202, 1302,
81	2104, 2105, 2106,
82	4104, 4105, 4106,
83	5104, 5105, 5106,
84	3002, 3005, 3008,
85	3202, 3205, 3208,
86	3302, 3305, 3308,
87
88	// [1][j]
89	2004, 2204, 2304, 4004, 4204, 4304, 5004, 5204, 5304,
90	2005, 2205, 2305, 4005, 4205, 4305, 5005, 5205, 5305,
91	2006, 2206, 2306, 4006, 4206, 4306, 5006, 5206, 5306,
92
93	// [2]
94	1003, 1203, 1303,
95	2107, 2108, 2109,
96	4107, 4108, 4109,
97	5107, 5108, 5109,
98	3003, 3006, 3009,
99	3203, 3206, 3209,
100	3303, 3306, 3309,
101
102	// [2][j]
103	2007, 2207, 2307, 4007, 4207, 4307, 5007, 5207, 5307,
104	2008, 2208, 2308, 4008, 4208, 4308, 5008, 5208, 5308,
105	2009, 2209, 2309, 4009, 4209, 4309, 5009, 5209, 5309,
106}
107
108var (
109	copy_zero     = zero
110	copy_one      = one
111	copy_pi       = pi
112	copy_slice    = slice
113	copy_sliceInt = sliceInt
114	// copy_hello    = hello // static init of copied strings defeats link -X; see #34675
115
116	// Could be handled without an initialization function, but
117	// requires special handling for "a = []byte("..."); b = a"
118	// which is not a likely case.
119	// copy_bytes = bytes
120	// https://codereview.appspot.com/171840043 is one approach to
121	// make this special case work.
122
123	copy_four, copy_five = four, five
124	copy_x               = x
125	// copy_y = y // static init of copied strings defeats link -X; see #34675
126	copy_nilslice = nilslice
127	copy_nilmap   = nilmap
128	copy_nilfunc  = nilfunc
129	copy_nilchan  = nilchan
130	copy_nilptr   = nilptr
131)
132
133var copy_a = a
134var copy_s = s
135var copy_c = c
136
137var copy_aa = aa
138var copy_as = as
139
140var copy_sa = sa
141var copy_ss = ss
142
143var copy_ca = ca
144var copy_cs = cs
145
146var copy_answers = answers
147
148var bx bool
149var b0 = false
150var b1 = true
151
152var fx float32
153var f0 = float32(0)
154var f1 = float32(1)
155
156var gx float64
157var g0 = float64(0)
158var g1 = float64(1)
159
160var ix int
161var i0 = 0
162var i1 = 1
163
164var jx uint
165var j0 = uint(0)
166var j1 = uint(1)
167
168var cx complex64
169var c0 = complex64(0)
170var c1 = complex64(1)
171
172var dx complex128
173var d0 = complex128(0)
174var d1 = complex128(1)
175
176var sx []int
177var s0 = []int{0, 0, 0}
178var s1 = []int{1, 2, 3}
179
180func fi() int { return 1 }
181
182var ax [10]int
183var a0 = [10]int{0, 0, 0}
184var a1 = [10]int{1, 2, 3, 4}
185
186type T struct{ X, Y int }
187
188var tx T
189var t0 = T{}
190var t0a = T{0, 0}
191var t0b = T{X: 0}
192var t1 = T{X: 1, Y: 2}
193var t1a = T{3, 4}
194
195var psx *[]int
196var ps0 = &[]int{0, 0, 0}
197var ps1 = &[]int{1, 2, 3}
198
199var pax *[10]int
200var pa0 = &[10]int{0, 0, 0}
201var pa1 = &[10]int{1, 2, 3}
202
203var ptx *T
204var pt0 = &T{}
205var pt0a = &T{0, 0}
206var pt0b = &T{X: 0}
207var pt1 = &T{X: 1, Y: 2}
208var pt1a = &T{3, 4}
209
210// The checks similar to
211// var copy_bx = bx
212// are commented out.  The  compiler no longer statically initializes them.
213// See issue 7665 and https://codereview.appspot.com/93200044.
214// If https://codereview.appspot.com/169040043 is submitted, and this
215// test is changed to pass -complete to the compiler, then we can
216// uncomment the copy lines again.
217
218// var copy_bx = bx
219var copy_b0 = b0
220var copy_b1 = b1
221
222// var copy_fx = fx
223var copy_f0 = f0
224var copy_f1 = f1
225
226// var copy_gx = gx
227var copy_g0 = g0
228var copy_g1 = g1
229
230// var copy_ix = ix
231var copy_i0 = i0
232var copy_i1 = i1
233
234// var copy_jx = jx
235var copy_j0 = j0
236var copy_j1 = j1
237
238// var copy_cx = cx
239var copy_c0 = c0
240var copy_c1 = c1
241
242// var copy_dx = dx
243var copy_d0 = d0
244var copy_d1 = d1
245
246// var copy_sx = sx
247var copy_s0 = s0
248var copy_s1 = s1
249
250// var copy_ax = ax
251var copy_a0 = a0
252var copy_a1 = a1
253
254// var copy_tx = tx
255var copy_t0 = t0
256var copy_t0a = t0a
257var copy_t0b = t0b
258var copy_t1 = t1
259var copy_t1a = t1a
260
261// var copy_psx = psx
262var copy_ps0 = ps0
263var copy_ps1 = ps1
264
265// var copy_pax = pax
266var copy_pa0 = pa0
267var copy_pa1 = pa1
268
269// var copy_ptx = ptx
270var copy_pt0 = pt0
271var copy_pt0a = pt0a
272var copy_pt0b = pt0b
273var copy_pt1 = pt1
274var copy_pt1a = pt1a
275
276var _ interface{} = 1
277
278type T1 int
279
280func (t *T1) M() {}
281
282type Mer interface {
283	M()
284}
285
286var _ Mer = (*T1)(nil)
287
288var Byte byte
289var PtrByte unsafe.Pointer = unsafe.Pointer(&Byte)
290
291var LitSXInit = &S{1, 2, 3}
292var LitSAnyXInit any = &S{4, 5, 6}
293
294func FS(x, y, z int) *S   { return &S{x, y, z} }
295func FSA(x, y, z int) any { return &S{x, y, z} }
296func F3(x int) *S         { return &S{x, x, x} }
297
298var LitSCallXInit = FS(7, 8, 9)
299var LitSAnyCallXInit any = FSA(10, 11, 12)
300
301var LitSRepeat = F3(1 + 2)
302
303func F0() *S { return &S{1, 2, 3} }
304
305var LitSNoArgs = F0()
306
307var myError = errors.New("mine")
308
309func gopherize(s string) string { return "gopher gopher gopher " + s }
310
311var animals = gopherize("badger")
312
313// These init funcs should optimize away.
314
315func init() {
316}
317
318func init() {
319	if false {
320	}
321}
322
323func init() {
324	for false {
325	}
326}
327
328// Actual test: check for init funcs in runtime data structures.
329
330type initTask struct {
331	state uint32
332	nfns  uint32
333}
334
335//go:linkname main_inittask main..inittask
336var main_inittask initTask
337
338func main() {
339	if nfns := main_inittask.nfns; nfns != 0 {
340		println(nfns)
341		panic("unexpected init funcs")
342	}
343}
344