github.com/karrick/go@v0.0.0-20170817181416-d5b0ec858b37/test/nilptr.go (about)

     1  // run
     2  
     3  // Copyright 2011 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  // Test that the implementation catches nil ptr indirection
     8  // in a large address space.
     9  
    10  package main
    11  
    12  import "unsafe"
    13  
    14  // Having a big address space means that indexing
    15  // at a 256 MB offset from a nil pointer might not
    16  // cause a memory access fault. This test checks
    17  // that Go is doing the correct explicit checks to catch
    18  // these nil pointer accesses, not just relying on the hardware.
    19  var dummy [256 << 20]byte // give us a big address space
    20  
    21  func main() {
    22  	// the test only tests what we intend to test
    23  	// if dummy starts in the first 256 MB of memory.
    24  	// otherwise there might not be anything mapped
    25  	// at the address that might be accidentally
    26  	// dereferenced below.
    27  	if uintptr(unsafe.Pointer(&dummy)) > 256<<20 {
    28  		panic("dummy too far out")
    29  	}
    30  
    31  	shouldPanic(p1)
    32  	shouldPanic(p2)
    33  	shouldPanic(p3)
    34  	shouldPanic(p4)
    35  	shouldPanic(p5)
    36  	shouldPanic(p6)
    37  	shouldPanic(p7)
    38  	shouldPanic(p8)
    39  	shouldPanic(p9)
    40  	shouldPanic(p10)
    41  	shouldPanic(p11)
    42  	shouldPanic(p12)
    43  	shouldPanic(p13)
    44  	shouldPanic(p14)
    45  	shouldPanic(p15)
    46  	shouldPanic(p16)
    47  }
    48  
    49  func shouldPanic(f func()) {
    50  	defer func() {
    51  		if recover() == nil {
    52  			panic("memory reference did not panic")
    53  		}
    54  	}()
    55  	f()
    56  }
    57  
    58  func p1() {
    59  	// Array index.
    60  	var p *[1 << 30]byte = nil
    61  	println(p[256<<20]) // very likely to be inside dummy, but should panic
    62  }
    63  
    64  var xb byte
    65  
    66  func p2() {
    67  	var p *[1 << 30]byte = nil
    68  	xb = 123
    69  
    70  	// Array index.
    71  	println(p[uintptr(unsafe.Pointer(&xb))]) // should panic
    72  }
    73  
    74  func p3() {
    75  	// Array to slice.
    76  	var p *[1 << 30]byte = nil
    77  	var x []byte = p[0:] // should panic
    78  	_ = x
    79  }
    80  
    81  var q *[1 << 30]byte
    82  
    83  func p4() {
    84  	// Array to slice.
    85  	var x []byte
    86  	var y = &x
    87  	*y = q[0:] // should crash (uses arraytoslice runtime routine)
    88  }
    89  
    90  func fb([]byte) {
    91  	panic("unreachable")
    92  }
    93  
    94  func p5() {
    95  	// Array to slice.
    96  	var p *[1 << 30]byte = nil
    97  	fb(p[0:]) // should crash
    98  }
    99  
   100  func p6() {
   101  	// Array to slice.
   102  	var p *[1 << 30]byte = nil
   103  	var _ []byte = p[10 : len(p)-10] // should crash
   104  }
   105  
   106  type T struct {
   107  	x [256 << 20]byte
   108  	i int
   109  }
   110  
   111  func f() *T {
   112  	return nil
   113  }
   114  
   115  var y *T
   116  var x = &y
   117  
   118  func p7() {
   119  	// Struct field access with large offset.
   120  	println(f().i) // should crash
   121  }
   122  
   123  func p8() {
   124  	// Struct field access with large offset.
   125  	println((*x).i) // should crash
   126  }
   127  
   128  func p9() {
   129  	// Struct field access with large offset.
   130  	var t *T
   131  	println(&t.i) // should crash
   132  }
   133  
   134  func p10() {
   135  	// Struct field access with large offset.
   136  	var t *T
   137  	println(t.i) // should crash
   138  }
   139  
   140  type T1 struct {
   141  	T
   142  }
   143  
   144  type T2 struct {
   145  	*T1
   146  }
   147  
   148  func p11() {
   149  	t := &T2{}
   150  	p := &t.i
   151  	println(*p)
   152  }
   153  
   154  // ADDR(DOT(IND(p))) needs a check also
   155  func p12() {
   156  	var p *T = nil
   157  	println(*(&((*p).i)))
   158  }
   159  
   160  // Tests suggested in golang.org/issue/6080.
   161  
   162  func p13() {
   163  	var x *[10]int
   164  	y := x[:]
   165  	_ = y
   166  }
   167  
   168  func p14() {
   169  	println((*[1]int)(nil)[:])
   170  }
   171  
   172  func p15() {
   173  	for i := range (*[1]int)(nil)[:] {
   174  		_ = i
   175  	}
   176  }
   177  
   178  func p16() {
   179  	for i, v := range (*[1]int)(nil)[:] {
   180  		_ = i + v
   181  	}
   182  }