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