File: checkbce.go

package info (click to toggle)
golang-1.8 1.8.1-1%2Bdeb9u1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 76,544 kB
  • sloc: asm: 55,864; ansic: 7,960; sh: 1,576; perl: 1,139; xml: 623; python: 286; javascript: 231; makefile: 109; cpp: 22; f90: 8; awk: 7
file content (116 lines) | stat: -rw-r--r-- 2,348 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// +build amd64
// errorcheck -0 -d=ssa/check_bce/debug=3

package main

func f0(a []int) {
	a[0] = 1 // ERROR "Found IsInBounds$"
	a[0] = 1
	a[6] = 1 // ERROR "Found IsInBounds$"
	a[6] = 1
	a[5] = 1
	a[5] = 1
}

func f1(a [256]int, i int) {
	useInt(a[i])     // ERROR "Found IsInBounds$"
	useInt(a[i%256]) // ERROR "Found IsInBounds$"
	useInt(a[i&255])
	useInt(a[i&17])

	if 4 <= i && i < len(a) {
		useInt(a[i])
		useInt(a[i-1]) // ERROR "Found IsInBounds$"
		// TODO: 'if 4 <= i && i < len(a)' gets rewritten to 'if uint(i - 4) < 256 - 4',
		// which the bounds checker cannot yet use to infer that the next line doesn't need a bounds check.
		useInt(a[i-4])
	}
}

func f2(a [256]int, i uint) {
	useInt(a[i]) // ERROR "Found IsInBounds$"
	useInt(a[i%256])
	useInt(a[i&255])
	useInt(a[i&17])
}

func f3(a [256]int, i uint8) {
	useInt(a[i])
	useInt(a[i+10])
	useInt(a[i+14])
}

func f4(a [27]int, i uint8) {
	useInt(a[i%15])
	useInt(a[i%19])
	useInt(a[i%27])
}

func f5(a []int) {
	if len(a) > 5 {
		useInt(a[5])
		useSlice(a[6:])
		useSlice(a[:6]) // ERROR "Found IsSliceInBounds$"
	}
}

func f6(a [32]int, b [64]int, i int) {
	useInt(a[uint32(i*0x07C4ACDD)>>27])
	useInt(b[uint64(i*0x07C4ACDD)>>58])
	useInt(a[uint(i*0x07C4ACDD)>>59])

	// The following bounds should not be removed because they can overflow.
	useInt(a[uint32(i*0x106297f105d0cc86)>>26]) // ERROR "Found IsInBounds$"
	useInt(b[uint64(i*0x106297f105d0cc86)>>57]) // ERROR "Found IsInBounds$"
	useInt(a[int32(i*0x106297f105d0cc86)>>26])  // ERROR "Found IsInBounds$"
	useInt(b[int64(i*0x106297f105d0cc86)>>57])  // ERROR "Found IsInBounds$"
}

func g1(a []int) {
	for i := range a {
		a[i] = i
		useSlice(a[:i+1])
		useSlice(a[:i])
	}
}

func g2(a []int) {
	useInt(a[3]) // ERROR "Found IsInBounds$"
	useInt(a[2])
	useInt(a[1])
	useInt(a[0])
}

func g3(a []int) {
	for i := range a[:256] { // ERROR "Found IsSliceInBounds$"
		useInt(a[i]) // ERROR "Found IsInBounds$"
	}
	b := a[:256]
	for i := range b {
		useInt(b[i])
	}
}

func g4(a [100]int) {
	for i := 10; i < 50; i++ {
		useInt(a[i-10])
		useInt(a[i])
		useInt(a[i+25])
		useInt(a[i+50])

		// The following are out of bounds.
		useInt(a[i-11]) // ERROR "Found IsInBounds$"
		useInt(a[i+51]) // ERROR "Found IsInBounds$"
	}
}

//go:noinline
func useInt(a int) {
}

//go:noinline
func useSlice(a []int) {
}

func main() {
}