github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/test/checkbce.go (about)

     1  // +build amd64
     2  // errorcheck -0 -d=ssa/check_bce/debug=3
     3  
     4  package main
     5  
     6  func f0(a []int) {
     7  	a[0] = 1 // ERROR "Found IsInBounds$"
     8  	a[0] = 1
     9  	a[6] = 1 // ERROR "Found IsInBounds$"
    10  	a[6] = 1
    11  	a[5] = 1
    12  	a[5] = 1
    13  }
    14  
    15  func f1(a [256]int, i int) {
    16  	var j int
    17  	useInt(a[i]) // ERROR "Found IsInBounds$"
    18  	j = i % 256
    19  	useInt(a[j]) // ERROR "Found IsInBounds$"
    20  	j = i & 255
    21  	useInt(a[j])
    22  	j = i & 17
    23  	useInt(a[j])
    24  
    25  	if 4 <= i && i < len(a) {
    26  		useInt(a[i])
    27  		useInt(a[i-1]) // ERROR "Found IsInBounds$"
    28  		// TODO: 'if 4 <= i && i < len(a)' gets rewritten to 'if uint(i - 4) < 256 - 4',
    29  		// which the bounds checker cannot yet use to infer that the next line doesn't need a bounds check.
    30  		useInt(a[i-4])
    31  	}
    32  }
    33  
    34  func f2(a [256]int, i uint) {
    35  	useInt(a[i]) // ERROR "Found IsInBounds$"
    36  	j := i % 256
    37  	useInt(a[j])
    38  	j = i & 255
    39  	useInt(a[j])
    40  	j = i & 17
    41  	useInt(a[j])
    42  }
    43  
    44  func f2a(a [35]int, i uint8) {
    45  	useInt(a[i]) // ERROR "Found IsInBounds$"
    46  	j := i & 34
    47  	useInt(a[j])
    48  	j = i & 17
    49  	useInt(a[j])
    50  }
    51  
    52  func f2b(a [35]int, i uint16) {
    53  	useInt(a[i]) // ERROR "Found IsInBounds$"
    54  	j := i & 34
    55  	useInt(a[j])
    56  	j = i & 17
    57  	useInt(a[j])
    58  }
    59  
    60  func f2c(a [35]int, i uint32) {
    61  	useInt(a[i]) // ERROR "Found IsInBounds$"
    62  	j := i & 34
    63  	useInt(a[j])
    64  	j = i & 17
    65  	useInt(a[j])
    66  }
    67  
    68  func f3(a [256]int, i uint8) {
    69  	useInt(a[i])
    70  	useInt(a[i+10])
    71  	useInt(a[i+14])
    72  }
    73  
    74  func f4(a [27]int, i uint8) {
    75  	useInt(a[i%15])
    76  	useInt(a[i%19])
    77  	useInt(a[i%27])
    78  }
    79  
    80  func f5(a []int) {
    81  	if len(a) > 5 {
    82  		useInt(a[5])
    83  		useSlice(a[6:])
    84  		useSlice(a[:6])
    85  	}
    86  }
    87  
    88  func f6(a [32]int, b [64]int, i int) {
    89  	useInt(a[uint32(i*0x07C4ACDD)>>27])
    90  	useInt(b[uint64(i*0x07C4ACDD)>>58])
    91  	useInt(a[uint(i*0x07C4ACDD)>>59])
    92  
    93  	// The following bounds should not be removed because they can overflow.
    94  	useInt(a[uint32(i*0x106297f105d0cc86)>>26]) // ERROR "Found IsInBounds$"
    95  	useInt(b[uint64(i*0x106297f105d0cc86)>>57]) // ERROR "Found IsInBounds$"
    96  	useInt(a[int32(i*0x106297f105d0cc86)>>26])  // ERROR "Found IsInBounds$"
    97  	useInt(b[int64(i*0x106297f105d0cc86)>>57])  // ERROR "Found IsInBounds$"
    98  }
    99  
   100  func g1(a []int) {
   101  	for i := range a {
   102  		a[i] = i
   103  		useSlice(a[:i+1])
   104  		useSlice(a[:i])
   105  	}
   106  }
   107  
   108  func g2(a []int) {
   109  	useInt(a[3]) // ERROR "Found IsInBounds$"
   110  	useInt(a[2])
   111  	useInt(a[1])
   112  	useInt(a[0])
   113  }
   114  
   115  func g3(a []int) {
   116  	for i := range a[:256] { // ERROR "Found IsSliceInBounds$"
   117  		useInt(a[i]) // ERROR "Found IsInBounds$"
   118  	}
   119  	b := a[:256]
   120  	for i := range b {
   121  		useInt(b[i])
   122  	}
   123  }
   124  
   125  func g4(a [100]int) {
   126  	for i := 10; i < 50; i++ {
   127  		useInt(a[i-10])
   128  		useInt(a[i])
   129  		useInt(a[i+25])
   130  		useInt(a[i+50])
   131  
   132  		// The following are out of bounds.
   133  		useInt(a[i-11]) // ERROR "Found IsInBounds$"
   134  		useInt(a[i+51]) // ERROR "Found IsInBounds$"
   135  	}
   136  }
   137  
   138  //go:noinline
   139  func useInt(a int) {
   140  }
   141  
   142  //go:noinline
   143  func useSlice(a []int) {
   144  }
   145  
   146  func main() {
   147  }