github.com/sbinet/go@v0.0.0-20160827155028-54d7de7dd62b/test/nilptr3_ssa.go (about)

     1  // errorcheck -0 -d=nil
     2  // +build amd64 arm amd64p32 386 arm64 mips64 mips64le
     3  
     4  // Copyright 2013 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 nil checks are removed.
     9  // Optimization is enabled.
    10  
    11  package p
    12  
    13  type Struct struct {
    14  	X int
    15  	Y float64
    16  }
    17  
    18  type BigStruct struct {
    19  	X int
    20  	Y float64
    21  	A [1 << 20]int
    22  	Z string
    23  }
    24  
    25  type Empty struct {
    26  }
    27  
    28  type Empty1 struct {
    29  	Empty
    30  }
    31  
    32  var (
    33  	intp       *int
    34  	arrayp     *[10]int
    35  	array0p    *[0]int
    36  	bigarrayp  *[1 << 26]int
    37  	structp    *Struct
    38  	bigstructp *BigStruct
    39  	emptyp     *Empty
    40  	empty1p    *Empty1
    41  )
    42  
    43  func f1() {
    44  	_ = *intp // ERROR "generated nil check"
    45  
    46  	// This one should be removed but the block copy needs
    47  	// to be turned into its own pseudo-op in order to see
    48  	// the indirect.
    49  	_ = *arrayp // ERROR "generated nil check"
    50  
    51  	// 0-byte indirect doesn't suffice.
    52  	// we don't registerize globals, so there are no removed.* nil checks.
    53  	_ = *array0p // ERROR "generated nil check"
    54  	_ = *array0p // ERROR "removed nil check"
    55  
    56  	_ = *intp    // ERROR "removed nil check"
    57  	_ = *arrayp  // ERROR "removed nil check"
    58  	_ = *structp // ERROR "generated nil check"
    59  	_ = *emptyp  // ERROR "generated nil check"
    60  	_ = *arrayp  // ERROR "removed nil check"
    61  }
    62  
    63  func f2() {
    64  	var (
    65  		intp       *int
    66  		arrayp     *[10]int
    67  		array0p    *[0]int
    68  		bigarrayp  *[1 << 20]int
    69  		structp    *Struct
    70  		bigstructp *BigStruct
    71  		emptyp     *Empty
    72  		empty1p    *Empty1
    73  	)
    74  
    75  	_ = *intp       // ERROR "generated nil check"
    76  	_ = *arrayp     // ERROR "generated nil check"
    77  	_ = *array0p    // ERROR "generated nil check"
    78  	_ = *array0p    // ERROR "removed.* nil check"
    79  	_ = *intp       // ERROR "removed.* nil check"
    80  	_ = *arrayp     // ERROR "removed.* nil check"
    81  	_ = *structp    // ERROR "generated nil check"
    82  	_ = *emptyp     // ERROR "generated nil check"
    83  	_ = *arrayp     // ERROR "removed.* nil check"
    84  	_ = *bigarrayp  // ERROR "generated nil check" ARM removed nil check before indirect!!
    85  	_ = *bigstructp // ERROR "generated nil check"
    86  	_ = *empty1p    // ERROR "generated nil check"
    87  }
    88  
    89  func fx10k() *[10000]int
    90  
    91  var b bool
    92  
    93  func f3(x *[10000]int) {
    94  	// Using a huge type and huge offsets so the compiler
    95  	// does not expect the memory hardware to fault.
    96  	_ = x[9999] // ERROR "generated nil check"
    97  
    98  	for {
    99  		if x[9999] != 0 { // ERROR "removed nil check"
   100  			break
   101  		}
   102  	}
   103  
   104  	x = fx10k()
   105  	_ = x[9999] // ERROR "generated nil check"
   106  	if b {
   107  		_ = x[9999] // ERROR "removed.* nil check"
   108  	} else {
   109  		_ = x[9999] // ERROR "removed.* nil check"
   110  	}
   111  	_ = x[9999] // ERROR "removed nil check"
   112  
   113  	x = fx10k()
   114  	if b {
   115  		_ = x[9999] // ERROR "generated nil check"
   116  	} else {
   117  		_ = x[9999] // ERROR "generated nil check"
   118  	}
   119  	_ = x[9999] // ERROR "generated nil check"
   120  
   121  	fx10k()
   122  	// This one is a bit redundant, if we figured out that
   123  	// x wasn't going to change across the function call.
   124  	// But it's a little complex to do and in practice doesn't
   125  	// matter enough.
   126  	_ = x[9999] // ERROR "removed nil check"
   127  }
   128  
   129  func f3a() {
   130  	x := fx10k()
   131  	y := fx10k()
   132  	z := fx10k()
   133  	_ = &x[9] // ERROR "generated nil check"
   134  	y = z
   135  	_ = &x[9] // ERROR "removed.* nil check"
   136  	x = y
   137  	_ = &x[9] // ERROR "generated nil check"
   138  }
   139  
   140  func f3b() {
   141  	x := fx10k()
   142  	y := fx10k()
   143  	_ = &x[9] // ERROR "generated nil check"
   144  	y = x
   145  	_ = &x[9] // ERROR "removed.* nil check"
   146  	x = y
   147  	_ = &x[9] // ERROR "removed.* nil check"
   148  }
   149  
   150  func fx10() *[10]int
   151  
   152  func f4(x *[10]int) {
   153  	// Most of these have no checks because a real memory reference follows,
   154  	// and the offset is small enough that if x is nil, the address will still be
   155  	// in the first unmapped page of memory.
   156  
   157  	_ = x[9] // ERROR "removed nil check"
   158  
   159  	for {
   160  		if x[9] != 0 { // ERROR "removed nil check"
   161  			break
   162  		}
   163  	}
   164  
   165  	x = fx10()
   166  	_ = x[9] // ERROR "generated nil check" // bug would like to remove before indirect
   167  	if b {
   168  		_ = x[9] // ERROR "removed nil check"
   169  	} else {
   170  		_ = x[9] // ERROR "removed nil check"
   171  	}
   172  	_ = x[9] // ERROR "removed nil check"
   173  
   174  	x = fx10()
   175  	if b {
   176  		_ = x[9] // ERROR "generated nil check"  // bug would like to remove before indirect
   177  	} else {
   178  		_ = &x[9] // ERROR "generated nil check"
   179  	}
   180  	_ = x[9] // ERROR "generated nil check"  // bug would like to remove before indirect
   181  
   182  	fx10()
   183  	_ = x[9] // ERROR "removed nil check"
   184  
   185  	x = fx10()
   186  	y := fx10()
   187  	_ = &x[9] // ERROR "generated nil check"
   188  	y = x
   189  	_ = &x[9] // ERROR "removed[a-z ]* nil check"
   190  	x = y
   191  	_ = &x[9] // ERROR "removed[a-z ]* nil check"
   192  }
   193  
   194  func f5(p *float32, q *float64, r *float32, s *float64) float64 {
   195  	x := float64(*p) // ERROR "removed nil check"
   196  	y := *q          // ERROR "removed nil check"
   197  	*r = 7           // ERROR "removed nil check"
   198  	*s = 9           // ERROR "removed nil check"
   199  	return x + y
   200  }
   201  
   202  type T [29]byte
   203  
   204  func f6(p, q *T) {
   205  	x := *p // ERROR "removed nil check"
   206  	*q = x  // ERROR "removed nil check"
   207  }
   208  
   209  func m1(m map[int][80]byte) byte {
   210  	v := m[3] // ERROR "removed nil check"
   211  	return v[5]
   212  }
   213  func m2(m map[int][800]byte) byte {
   214  	v := m[3] // ERROR "removed nil check"
   215  	return v[5]
   216  }
   217  func m3(m map[int][80]byte) (byte, bool) {
   218  	v, ok := m[3] // ERROR "removed nil check"
   219  	return v[5], ok
   220  }
   221  func m4(m map[int][800]byte) (byte, bool) {
   222  	v, ok := m[3] // ERROR "removed nil check"
   223  	return v[5], ok
   224  }
   225  func p1() byte {
   226  	p := new([100]byte)
   227  	return p[5] // ERROR "removed nil check"
   228  }
   229  
   230  // make sure not to do nil check for access of PAUTOHEAP
   231  //go:noinline
   232  func (p *Struct) m() {}
   233  func c1() {
   234  	var x Struct
   235  	func() { x.m() }() // ERROR "removed nil check"
   236  }