Source file test/noinit.go

     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  
    12  package main
    13  
    14  import (
    15  	"errors"
    16  	"unsafe"
    17  )
    18  
    19  // All these initializations should be done at link time.
    20  
    21  type S struct{ a, b, c int }
    22  type SS struct{ aa, bb, cc S }
    23  type SA struct{ a, b, c [3]int }
    24  type SC struct{ a, b, c []int }
    25  
    26  var (
    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  
    43  var a = [3]int{1001, 1002, 1003}
    44  var s = S{1101, 1102, 1103}
    45  var c = []int{1201, 1202, 1203}
    46  
    47  var aa = [3][3]int{[3]int{2001, 2002, 2003}, [3]int{2004, 2005, 2006}, [3]int{2007, 2008, 2009}}
    48  var as = [3]S{S{2101, 2102, 2103}, S{2104, 2105, 2106}, S{2107, 2108, 2109}}
    49  
    50  var sa = SA{[3]int{3001, 3002, 3003}, [3]int{3004, 3005, 3006}, [3]int{3007, 3008, 3009}}
    51  var ss = SS{S{3101, 3102, 3103}, S{3104, 3105, 3106}, S{3107, 3108, 3109}}
    52  
    53  var ca = [][3]int{[3]int{4001, 4002, 4003}, [3]int{4004, 4005, 4006}, [3]int{4007, 4008, 4009}}
    54  var cs = []S{S{4101, 4102, 4103}, S{4104, 4105, 4106}, S{4107, 4108, 4109}}
    55  
    56  var 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  
   108  var (
   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  
   133  var copy_a = a
   134  var copy_s = s
   135  var copy_c = c
   136  
   137  var copy_aa = aa
   138  var copy_as = as
   139  
   140  var copy_sa = sa
   141  var copy_ss = ss
   142  
   143  var copy_ca = ca
   144  var copy_cs = cs
   145  
   146  var copy_answers = answers
   147  
   148  var bx bool
   149  var b0 = false
   150  var b1 = true
   151  
   152  var fx float32
   153  var f0 = float32(0)
   154  var f1 = float32(1)
   155  
   156  var gx float64
   157  var g0 = float64(0)
   158  var g1 = float64(1)
   159  
   160  var ix int
   161  var i0 = 0
   162  var i1 = 1
   163  
   164  var jx uint
   165  var j0 = uint(0)
   166  var j1 = uint(1)
   167  
   168  var cx complex64
   169  var c0 = complex64(0)
   170  var c1 = complex64(1)
   171  
   172  var dx complex128
   173  var d0 = complex128(0)
   174  var d1 = complex128(1)
   175  
   176  var sx []int
   177  var s0 = []int{0, 0, 0}
   178  var s1 = []int{1, 2, 3}
   179  
   180  func fi() int { return 1 }
   181  
   182  var ax [10]int
   183  var a0 = [10]int{0, 0, 0}
   184  var a1 = [10]int{1, 2, 3, 4}
   185  
   186  type T struct{ X, Y int }
   187  
   188  var tx T
   189  var t0 = T{}
   190  var t0a = T{0, 0}
   191  var t0b = T{X: 0}
   192  var t1 = T{X: 1, Y: 2}
   193  var t1a = T{3, 4}
   194  
   195  var psx *[]int
   196  var ps0 = &[]int{0, 0, 0}
   197  var ps1 = &[]int{1, 2, 3}
   198  
   199  var pax *[10]int
   200  var pa0 = &[10]int{0, 0, 0}
   201  var pa1 = &[10]int{1, 2, 3}
   202  
   203  var ptx *T
   204  var pt0 = &T{}
   205  var pt0a = &T{0, 0}
   206  var pt0b = &T{X: 0}
   207  var pt1 = &T{X: 1, Y: 2}
   208  var 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
   219  var copy_b0 = b0
   220  var copy_b1 = b1
   221  
   222  // var copy_fx = fx
   223  var copy_f0 = f0
   224  var copy_f1 = f1
   225  
   226  // var copy_gx = gx
   227  var copy_g0 = g0
   228  var copy_g1 = g1
   229  
   230  // var copy_ix = ix
   231  var copy_i0 = i0
   232  var copy_i1 = i1
   233  
   234  // var copy_jx = jx
   235  var copy_j0 = j0
   236  var copy_j1 = j1
   237  
   238  // var copy_cx = cx
   239  var copy_c0 = c0
   240  var copy_c1 = c1
   241  
   242  // var copy_dx = dx
   243  var copy_d0 = d0
   244  var copy_d1 = d1
   245  
   246  // var copy_sx = sx
   247  var copy_s0 = s0
   248  var copy_s1 = s1
   249  
   250  // var copy_ax = ax
   251  var copy_a0 = a0
   252  var copy_a1 = a1
   253  
   254  // var copy_tx = tx
   255  var copy_t0 = t0
   256  var copy_t0a = t0a
   257  var copy_t0b = t0b
   258  var copy_t1 = t1
   259  var copy_t1a = t1a
   260  
   261  // var copy_psx = psx
   262  var copy_ps0 = ps0
   263  var copy_ps1 = ps1
   264  
   265  // var copy_pax = pax
   266  var copy_pa0 = pa0
   267  var copy_pa1 = pa1
   268  
   269  // var copy_ptx = ptx
   270  var copy_pt0 = pt0
   271  var copy_pt0a = pt0a
   272  var copy_pt0b = pt0b
   273  var copy_pt1 = pt1
   274  var copy_pt1a = pt1a
   275  
   276  var _ interface{} = 1
   277  
   278  type T1 int
   279  
   280  func (t *T1) M() {}
   281  
   282  type Mer interface {
   283  	M()
   284  }
   285  
   286  var _ Mer = (*T1)(nil)
   287  
   288  var Byte byte
   289  var PtrByte unsafe.Pointer = unsafe.Pointer(&Byte)
   290  
   291  var LitSXInit = &S{1, 2, 3}
   292  var LitSAnyXInit any = &S{4, 5, 6}
   293  
   294  func FS(x, y, z int) *S   { return &S{x, y, z} }
   295  func FSA(x, y, z int) any { return &S{x, y, z} }
   296  func F3(x int) *S         { return &S{x, x, x} }
   297  
   298  var LitSCallXInit = FS(7, 8, 9)
   299  var LitSAnyCallXInit any = FSA(10, 11, 12)
   300  
   301  var LitSRepeat = F3(1 + 2)
   302  
   303  func F0() *S { return &S{1, 2, 3} }
   304  
   305  var LitSNoArgs = F0()
   306  
   307  var myError = errors.New("mine")
   308  
   309  func gopherize(s string) string { return "gopher gopher gopher " + s }
   310  
   311  var animals = gopherize("badger")
   312  
   313  // These init funcs should optimize away.
   314  
   315  func init() {
   316  }
   317  
   318  func init() {
   319  	if false {
   320  	}
   321  }
   322  
   323  func init() {
   324  	for false {
   325  	}
   326  }
   327  
   328  // Actual test: check for init funcs in runtime data structures.
   329  
   330  type initTask struct {
   331  	state uint32
   332  	nfns  uint32
   333  }
   334  
   335  //go:linkname main_inittask main..inittask
   336  var main_inittask initTask
   337  
   338  func main() {
   339  	if nfns := main_inittask.nfns; nfns != 0 {
   340  		println(nfns)
   341  		panic("unexpected init funcs")
   342  	}
   343  }
   344  

View as plain text