Black Lives Matter. Support the Equal Justice Initiative.

Source file test/nilptr.go

Documentation: test

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

View as plain text