Source file test/nilptr.go

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

View as plain text