summaryrefslogtreecommitdiffstats
path: root/test/bounds.go
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 13:18:25 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 13:18:25 +0000
commit109be507377fe7f6e8819ac94041d3fdcdf6fd2f (patch)
tree2806a689f8fab4a2ec9fc949830ef270a91d667d /test/bounds.go
parentInitial commit. (diff)
downloadgolang-1.19-109be507377fe7f6e8819ac94041d3fdcdf6fd2f.tar.xz
golang-1.19-109be507377fe7f6e8819ac94041d3fdcdf6fd2f.zip
Adding upstream version 1.19.8.upstream/1.19.8upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'test/bounds.go')
-rw-r--r--test/bounds.go284
1 files changed, 284 insertions, 0 deletions
diff --git a/test/bounds.go b/test/bounds.go
new file mode 100644
index 0000000..aa1d51b
--- /dev/null
+++ b/test/bounds.go
@@ -0,0 +1,284 @@
+// errorcheck -0 -m -l
+
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Test, using compiler diagnostic flags, that bounds check elimination
+// is eliminating the correct checks.
+
+package foo
+
+var (
+ s []int
+
+ a1 [1]int
+ a1k [1000]int
+ a100k [100000]int
+
+ p1 *[1]int
+ p1k *[1000]int
+ p100k *[100000]int
+
+ i int
+ ui uint
+ i8 int8
+ ui8 uint8
+ i16 int16
+ ui16 uint16
+ i32 int32
+ ui32 uint32
+ i64 int64
+ ui64 uint64
+)
+
+func main() {
+ // Most things need checks.
+ use(s[i])
+ use(a1[i])
+ use(a1k[i])
+ use(a100k[i])
+ use(p1[i])
+ use(p1k[i])
+ use(p100k[i])
+
+ use(s[ui])
+ use(a1[ui])
+ use(a1k[ui])
+ use(a100k[ui])
+ use(p1[ui])
+ use(p1k[ui])
+ use(p100k[ui])
+
+ use(s[i8])
+ use(a1[i8])
+ use(a1k[i8])
+ use(a100k[i8])
+ use(p1[i8])
+ use(p1k[i8])
+ use(p100k[i8])
+
+ // Unsigned 8-bit numbers don't need checks for len >= 2⁸.
+ use(s[ui8])
+ use(a1[ui8])
+ use(a1k[ui8]) // ERROR "index bounds check elided"
+ use(a100k[ui8]) // ERROR "index bounds check elided"
+ use(p1[ui8])
+ use(p1k[ui8]) // ERROR "index bounds check elided"
+ use(p100k[ui8]) // ERROR "index bounds check elided"
+
+ use(s[i16])
+ use(a1[i16])
+ use(a1k[i16])
+ use(a100k[i16])
+ use(p1[i16])
+ use(p1k[i16])
+ use(p100k[i16])
+
+ // Unsigned 16-bit numbers don't need checks for len >= 2¹⁶.
+ use(s[ui16])
+ use(a1[ui16])
+ use(a1k[ui16])
+ use(a100k[ui16]) // ERROR "index bounds check elided"
+ use(p1[ui16])
+ use(p1k[ui16])
+ use(p100k[ui16]) // ERROR "index bounds check elided"
+
+ use(s[i32])
+ use(a1[i32])
+ use(a1k[i32])
+ use(a100k[i32])
+ use(p1[i32])
+ use(p1k[i32])
+ use(p100k[i32])
+
+ use(s[ui32])
+ use(a1[ui32])
+ use(a1k[ui32])
+ use(a100k[ui32])
+ use(p1[ui32])
+ use(p1k[ui32])
+ use(p100k[ui32])
+
+ use(s[i64])
+ use(a1[i64])
+ use(a1k[i64])
+ use(a100k[i64])
+ use(p1[i64])
+ use(p1k[i64])
+ use(p100k[i64])
+
+ use(s[ui64])
+ use(a1[ui64])
+ use(a1k[ui64])
+ use(a100k[ui64])
+ use(p1[ui64])
+ use(p1k[ui64])
+ use(p100k[ui64])
+
+ // Mod truncates the maximum value to one less than the argument,
+ // but signed mod can be negative, so only unsigned mod counts.
+ use(s[i%999])
+ use(a1[i%999])
+ use(a1k[i%999])
+ use(a100k[i%999])
+ use(p1[i%999])
+ use(p1k[i%999])
+ use(p100k[i%999])
+
+ use(s[ui%999])
+ use(a1[ui%999])
+ use(a1k[ui%999]) // ERROR "index bounds check elided"
+ use(a100k[ui%999]) // ERROR "index bounds check elided"
+ use(p1[ui%999])
+ use(p1k[ui%999]) // ERROR "index bounds check elided"
+ use(p100k[ui%999]) // ERROR "index bounds check elided"
+
+ use(s[i%1000])
+ use(a1[i%1000])
+ use(a1k[i%1000])
+ use(a100k[i%1000])
+ use(p1[i%1000])
+ use(p1k[i%1000])
+ use(p100k[i%1000])
+
+ use(s[ui%1000])
+ use(a1[ui%1000])
+ use(a1k[ui%1000]) // ERROR "index bounds check elided"
+ use(a100k[ui%1000]) // ERROR "index bounds check elided"
+ use(p1[ui%1000])
+ use(p1k[ui%1000]) // ERROR "index bounds check elided"
+ use(p100k[ui%1000]) // ERROR "index bounds check elided"
+
+ use(s[i%1001])
+ use(a1[i%1001])
+ use(a1k[i%1001])
+ use(a100k[i%1001])
+ use(p1[i%1001])
+ use(p1k[i%1001])
+ use(p100k[i%1001])
+
+ use(s[ui%1001])
+ use(a1[ui%1001])
+ use(a1k[ui%1001])
+ use(a100k[ui%1001]) // ERROR "index bounds check elided"
+ use(p1[ui%1001])
+ use(p1k[ui%1001])
+ use(p100k[ui%1001]) // ERROR "index bounds check elided"
+
+ // Bitwise and truncates the maximum value to the mask value.
+ // The result (for a positive mask) cannot be negative, so elision
+ // applies to both signed and unsigned indexes.
+ use(s[i&999])
+ use(a1[i&999])
+ use(a1k[i&999]) // ERROR "index bounds check elided"
+ use(a100k[i&999]) // ERROR "index bounds check elided"
+ use(p1[i&999])
+ use(p1k[i&999]) // ERROR "index bounds check elided"
+ use(p100k[i&999]) // ERROR "index bounds check elided"
+
+ use(s[ui&999])
+ use(a1[ui&999])
+ use(a1k[ui&999]) // ERROR "index bounds check elided"
+ use(a100k[ui&999]) // ERROR "index bounds check elided"
+ use(p1[ui&999])
+ use(p1k[ui&999]) // ERROR "index bounds check elided"
+ use(p100k[ui&999]) // ERROR "index bounds check elided"
+
+ use(s[i&1000])
+ use(a1[i&1000])
+ use(a1k[i&1000])
+ use(a100k[i&1000]) // ERROR "index bounds check elided"
+ use(p1[i&1000])
+ use(p1k[i&1000])
+ use(p100k[i&1000]) // ERROR "index bounds check elided"
+
+ use(s[ui&1000])
+ use(a1[ui&1000])
+ use(a1k[ui&1000])
+ use(a100k[ui&1000]) // ERROR "index bounds check elided"
+ use(p1[ui&1000])
+ use(p1k[ui&1000])
+ use(p100k[ui&1000]) // ERROR "index bounds check elided"
+
+ use(a1[i&^-1]) // ERROR "index bounds check elided"
+ use(a1[i&^0])
+ use(a1[i&^-2])
+ use(a1[i&^1])
+ use(a1k[i&^-1]) // ERROR "index bounds check elided"
+ use(a1k[i&^0])
+ use(a1k[i&^-2]) // ERROR "index bounds check elided"
+ use(a1k[i&^1])
+ use(a1k[i8&^0])
+ use(a1k[i8&^-128]) // ERROR "index bounds check elided"
+ use(a1k[ui8&^1]) // ERROR "index bounds check elided"
+ use(a1k[ui16&^0xf000])
+ use(a1k[ui16&^0xff00]) // ERROR "index bounds check elided"
+
+ // Right shift cuts the effective number of bits in the index,
+ // but only for unsigned (signed stays negative).
+ use(s[i32>>22])
+ use(a1[i32>>22])
+ use(a1k[i32>>22])
+ use(a100k[i32>>22])
+ use(p1[i32>>22])
+ use(p1k[i32>>22])
+ use(p100k[i32>>22])
+
+ use(s[ui32>>22])
+ use(a1[ui32>>22])
+ use(a1k[ui32>>22])
+ use(a100k[ui32>>22]) // ERROR "index bounds check elided"
+ use(p1[ui32>>22])
+ use(p1k[ui32>>22])
+ use(p100k[ui32>>22]) // ERROR "index bounds check elided"
+
+ use(s[i32>>23])
+ use(a1[i32>>23])
+ use(a1k[i32>>23])
+ use(a100k[i32>>23])
+ use(p1[i32>>23])
+ use(p1k[i32>>23])
+ use(p100k[i32>>23])
+
+ use(s[ui32>>23])
+ use(a1[ui32>>23])
+ use(a1k[ui32>>23]) // ERROR "index bounds check elided"
+ use(a100k[ui32>>23]) // ERROR "index bounds check elided"
+ use(p1[ui32>>23])
+ use(p1k[ui32>>23]) // ERROR "index bounds check elided"
+ use(p100k[ui32>>23]) // ERROR "index bounds check elided"
+
+ // Division cuts the range like right shift does.
+ use(s[i/1e6])
+ use(a1[i/1e6])
+ use(a1k[i/1e6])
+ use(a100k[i/1e6])
+ use(p1[i/1e6])
+ use(p1k[i/1e6])
+ use(p100k[i/1e6])
+
+ use(s[ui/1e6])
+ use(a1[ui/1e6])
+ use(a1k[ui/1e6])
+ use(p1[ui/1e6])
+ use(p1k[ui/1e6])
+
+ use(s[i/1e7])
+ use(a1[i/1e7])
+ use(a1k[i/1e7])
+ use(a100k[i/1e7])
+ use(p1[i/1e7])
+ use(p1k[i/1e7])
+ use(p100k[i/1e7])
+
+ use(s[ui/1e7])
+ use(a1[ui/1e7])
+ use(p1[ui/1e7])
+}
+
+var sum int
+
+func use(x int) {
+ sum += x
+}