modernc.org/gc@v1.0.1-0.20240304020402-f0dba7c97c2b/testdata/errchk/test/fixedbugs/issue15002.go (about)

     1  // run
     2  // +build amd64
     3  // +build linux darwin
     4  
     5  // Copyright 2016 The Go Authors. All rights reserved.
     6  // Use of this source code is governed by a BSD-style
     7  // license that can be found in the LICENSE file.
     8  
     9  package main
    10  
    11  import (
    12  	"fmt"
    13  	"syscall"
    14  )
    15  
    16  // Use global variables so the compiler
    17  // doesn't know that they are constants.
    18  var p = syscall.Getpagesize()
    19  var zero = 0
    20  var one = 1
    21  
    22  func main() {
    23  	// Allocate 2 pages of memory.
    24  	b, err := syscall.Mmap(-1, 0, 2*p, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_ANON|syscall.MAP_PRIVATE)
    25  	if err != nil {
    26  		panic(err)
    27  	}
    28  	// Mark the second page as faulting.
    29  	err = syscall.Mprotect(b[p:], syscall.PROT_NONE)
    30  	if err != nil {
    31  		panic(err)
    32  	}
    33  	// Get a slice pointing to the last byte of the good page.
    34  	x := b[p-one : p]
    35  
    36  	test16(x)
    37  	test16i(x, 0)
    38  	test32(x)
    39  	test32i(x, 0)
    40  	test64(x)
    41  	test64i(x, 0)
    42  }
    43  
    44  func test16(x []byte) uint16 {
    45  	defer func() {
    46  		r := recover()
    47  		if r == nil {
    48  			panic("no fault or bounds check failure happened")
    49  		}
    50  		s := fmt.Sprintf("%s", r)
    51  		if s != "runtime error: index out of range" {
    52  			panic("bad panic: " + s)
    53  		}
    54  	}()
    55  	// Try to read 2 bytes from x.
    56  	return uint16(x[0]) | uint16(x[1])<<8
    57  
    58  	// We expect to get an "index out of range" error from x[1].
    59  	// If we promote the first load to a 2-byte load, it will segfault, which we don't want.
    60  }
    61  
    62  func test16i(x []byte, i int) uint16 {
    63  	defer func() {
    64  		r := recover()
    65  		if r == nil {
    66  			panic("no fault or bounds check failure happened")
    67  		}
    68  		s := fmt.Sprintf("%s", r)
    69  		if s != "runtime error: index out of range" {
    70  			panic("bad panic: " + s)
    71  		}
    72  	}()
    73  	return uint16(x[i]) | uint16(x[i+1])<<8
    74  }
    75  
    76  func test32(x []byte) uint32 {
    77  	defer func() {
    78  		r := recover()
    79  		if r == nil {
    80  			panic("no fault or bounds check failure happened")
    81  		}
    82  		s := fmt.Sprintf("%s", r)
    83  		if s != "runtime error: index out of range" {
    84  			panic("bad panic: " + s)
    85  		}
    86  	}()
    87  	return uint32(x[0]) | uint32(x[1])<<8 | uint32(x[2])<<16 | uint32(x[3])<<24
    88  }
    89  
    90  func test32i(x []byte, i int) uint32 {
    91  	defer func() {
    92  		r := recover()
    93  		if r == nil {
    94  			panic("no fault or bounds check failure happened")
    95  		}
    96  		s := fmt.Sprintf("%s", r)
    97  		if s != "runtime error: index out of range" {
    98  			panic("bad panic: " + s)
    99  		}
   100  	}()
   101  	return uint32(x[i]) | uint32(x[i+1])<<8 | uint32(x[i+2])<<16 | uint32(x[i+3])<<24
   102  }
   103  
   104  func test64(x []byte) uint64 {
   105  	defer func() {
   106  		r := recover()
   107  		if r == nil {
   108  			panic("no fault or bounds check failure happened")
   109  		}
   110  		s := fmt.Sprintf("%s", r)
   111  		if s != "runtime error: index out of range" {
   112  			panic("bad panic: " + s)
   113  		}
   114  	}()
   115  	return uint64(x[0]) | uint64(x[1])<<8 | uint64(x[2])<<16 | uint64(x[3])<<24 |
   116  		uint64(x[4])<<32 | uint64(x[5])<<40 | uint64(x[6])<<48 | uint64(x[7])<<56
   117  }
   118  
   119  func test64i(x []byte, i int) uint64 {
   120  	defer func() {
   121  		r := recover()
   122  		if r == nil {
   123  			panic("no fault or bounds check failure happened")
   124  		}
   125  		s := fmt.Sprintf("%s", r)
   126  		if s != "runtime error: index out of range" {
   127  			panic("bad panic: " + s)
   128  		}
   129  	}()
   130  	return uint64(x[i+0]) | uint64(x[i+1])<<8 | uint64(x[i+2])<<16 | uint64(x[i+3])<<24 |
   131  		uint64(x[i+4])<<32 | uint64(x[i+5])<<40 | uint64(x[i+6])<<48 | uint64(x[i+7])<<56
   132  }