Skip to content

Commit 741a19a

Browse files
committed
runtime: move bounds check constants to internal/abi
For future use by the compiler. Change-Id: Id3da62006b283ac38008261c0ef88aaf71ef5896 Reviewed-on: https://go-review.googlesource.com/c/go/+/682456 Reviewed-by: David Chase <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Michael Knyszek <[email protected]>
1 parent ce05ad4 commit 741a19a

File tree

4 files changed

+73
-69
lines changed

4 files changed

+73
-69
lines changed

src/internal/abi/bounds.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2025 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package abi
6+
7+
// This type and constants are for encoding different
8+
// kinds of bounds check failures.
9+
type BoundsErrorCode uint8
10+
11+
const (
12+
BoundsIndex BoundsErrorCode = iota // s[x], 0 <= x < len(s) failed
13+
BoundsSliceAlen // s[?:x], 0 <= x <= len(s) failed
14+
BoundsSliceAcap // s[?:x], 0 <= x <= cap(s) failed
15+
BoundsSliceB // s[x:y], 0 <= x <= y failed (but boundsSliceA didn't happen)
16+
BoundsSlice3Alen // s[?:?:x], 0 <= x <= len(s) failed
17+
BoundsSlice3Acap // s[?:?:x], 0 <= x <= cap(s) failed
18+
BoundsSlice3B // s[?:x:y], 0 <= x <= y failed (but boundsSlice3A didn't happen)
19+
BoundsSlice3C // s[x:y:?], 0 <= x <= y failed (but boundsSlice3A/B didn't happen)
20+
BoundsConvert // (*[x]T)(s), 0 <= x <= len(s) failed
21+
)

src/runtime/error.go

Lines changed: 18 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -132,52 +132,34 @@ type boundsError struct {
132132
// Instead, we keep track of whether x should be interpreted as signed or unsigned.
133133
// y is known to be nonnegative and to fit in an int.
134134
signed bool
135-
code boundsErrorCode
135+
code abi.BoundsErrorCode
136136
}
137137

138-
type boundsErrorCode uint8
139-
140-
const (
141-
boundsIndex boundsErrorCode = iota // s[x], 0 <= x < len(s) failed
142-
143-
boundsSliceAlen // s[?:x], 0 <= x <= len(s) failed
144-
boundsSliceAcap // s[?:x], 0 <= x <= cap(s) failed
145-
boundsSliceB // s[x:y], 0 <= x <= y failed (but boundsSliceA didn't happen)
146-
147-
boundsSlice3Alen // s[?:?:x], 0 <= x <= len(s) failed
148-
boundsSlice3Acap // s[?:?:x], 0 <= x <= cap(s) failed
149-
boundsSlice3B // s[?:x:y], 0 <= x <= y failed (but boundsSlice3A didn't happen)
150-
boundsSlice3C // s[x:y:?], 0 <= x <= y failed (but boundsSlice3A/B didn't happen)
151-
152-
boundsConvert // (*[x]T)(s), 0 <= x <= len(s) failed
153-
// Note: in the above, len(s) and cap(s) are stored in y
154-
)
155-
156138
// boundsErrorFmts provide error text for various out-of-bounds panics.
157139
// Note: if you change these strings, you should adjust the size of the buffer
158140
// in boundsError.Error below as well.
159141
var boundsErrorFmts = [...]string{
160-
boundsIndex: "index out of range [%x] with length %y",
161-
boundsSliceAlen: "slice bounds out of range [:%x] with length %y",
162-
boundsSliceAcap: "slice bounds out of range [:%x] with capacity %y",
163-
boundsSliceB: "slice bounds out of range [%x:%y]",
164-
boundsSlice3Alen: "slice bounds out of range [::%x] with length %y",
165-
boundsSlice3Acap: "slice bounds out of range [::%x] with capacity %y",
166-
boundsSlice3B: "slice bounds out of range [:%x:%y]",
167-
boundsSlice3C: "slice bounds out of range [%x:%y:]",
168-
boundsConvert: "cannot convert slice with length %y to array or pointer to array with length %x",
142+
abi.BoundsIndex: "index out of range [%x] with length %y",
143+
abi.BoundsSliceAlen: "slice bounds out of range [:%x] with length %y",
144+
abi.BoundsSliceAcap: "slice bounds out of range [:%x] with capacity %y",
145+
abi.BoundsSliceB: "slice bounds out of range [%x:%y]",
146+
abi.BoundsSlice3Alen: "slice bounds out of range [::%x] with length %y",
147+
abi.BoundsSlice3Acap: "slice bounds out of range [::%x] with capacity %y",
148+
abi.BoundsSlice3B: "slice bounds out of range [:%x:%y]",
149+
abi.BoundsSlice3C: "slice bounds out of range [%x:%y:]",
150+
abi.BoundsConvert: "cannot convert slice with length %y to array or pointer to array with length %x",
169151
}
170152

171153
// boundsNegErrorFmts are overriding formats if x is negative. In this case there's no need to report y.
172154
var boundsNegErrorFmts = [...]string{
173-
boundsIndex: "index out of range [%x]",
174-
boundsSliceAlen: "slice bounds out of range [:%x]",
175-
boundsSliceAcap: "slice bounds out of range [:%x]",
176-
boundsSliceB: "slice bounds out of range [%x:]",
177-
boundsSlice3Alen: "slice bounds out of range [::%x]",
178-
boundsSlice3Acap: "slice bounds out of range [::%x]",
179-
boundsSlice3B: "slice bounds out of range [:%x:]",
180-
boundsSlice3C: "slice bounds out of range [%x::]",
155+
abi.BoundsIndex: "index out of range [%x]",
156+
abi.BoundsSliceAlen: "slice bounds out of range [:%x]",
157+
abi.BoundsSliceAcap: "slice bounds out of range [:%x]",
158+
abi.BoundsSliceB: "slice bounds out of range [%x:]",
159+
abi.BoundsSlice3Alen: "slice bounds out of range [::%x]",
160+
abi.BoundsSlice3Acap: "slice bounds out of range [::%x]",
161+
abi.BoundsSlice3B: "slice bounds out of range [:%x:]",
162+
abi.BoundsSlice3C: "slice bounds out of range [%x::]",
181163
}
182164

183165
func (e boundsError) RuntimeError() {}

src/runtime/panic.go

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -112,97 +112,97 @@ func panicCheck2(err string) {
112112
//go:yeswritebarrierrec
113113
func goPanicIndex(x int, y int) {
114114
panicCheck1(sys.GetCallerPC(), "index out of range")
115-
panic(boundsError{x: int64(x), signed: true, y: y, code: boundsIndex})
115+
panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsIndex})
116116
}
117117

118118
//go:yeswritebarrierrec
119119
func goPanicIndexU(x uint, y int) {
120120
panicCheck1(sys.GetCallerPC(), "index out of range")
121-
panic(boundsError{x: int64(x), signed: false, y: y, code: boundsIndex})
121+
panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsIndex})
122122
}
123123

124124
// failures in the comparisons for s[:x], 0 <= x <= y (y == len(s) or cap(s))
125125
//
126126
//go:yeswritebarrierrec
127127
func goPanicSliceAlen(x int, y int) {
128128
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
129-
panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSliceAlen})
129+
panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSliceAlen})
130130
}
131131

132132
//go:yeswritebarrierrec
133133
func goPanicSliceAlenU(x uint, y int) {
134134
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
135-
panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSliceAlen})
135+
panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSliceAlen})
136136
}
137137

138138
//go:yeswritebarrierrec
139139
func goPanicSliceAcap(x int, y int) {
140140
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
141-
panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSliceAcap})
141+
panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSliceAcap})
142142
}
143143

144144
//go:yeswritebarrierrec
145145
func goPanicSliceAcapU(x uint, y int) {
146146
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
147-
panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSliceAcap})
147+
panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSliceAcap})
148148
}
149149

150150
// failures in the comparisons for s[x:y], 0 <= x <= y
151151
//
152152
//go:yeswritebarrierrec
153153
func goPanicSliceB(x int, y int) {
154154
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
155-
panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSliceB})
155+
panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSliceB})
156156
}
157157

158158
//go:yeswritebarrierrec
159159
func goPanicSliceBU(x uint, y int) {
160160
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
161-
panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSliceB})
161+
panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSliceB})
162162
}
163163

164164
// failures in the comparisons for s[::x], 0 <= x <= y (y == len(s) or cap(s))
165165
func goPanicSlice3Alen(x int, y int) {
166166
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
167-
panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3Alen})
167+
panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSlice3Alen})
168168
}
169169
func goPanicSlice3AlenU(x uint, y int) {
170170
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
171-
panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3Alen})
171+
panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSlice3Alen})
172172
}
173173
func goPanicSlice3Acap(x int, y int) {
174174
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
175-
panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3Acap})
175+
panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSlice3Acap})
176176
}
177177
func goPanicSlice3AcapU(x uint, y int) {
178178
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
179-
panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3Acap})
179+
panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSlice3Acap})
180180
}
181181

182182
// failures in the comparisons for s[:x:y], 0 <= x <= y
183183
func goPanicSlice3B(x int, y int) {
184184
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
185-
panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3B})
185+
panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSlice3B})
186186
}
187187
func goPanicSlice3BU(x uint, y int) {
188188
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
189-
panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3B})
189+
panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSlice3B})
190190
}
191191

192192
// failures in the comparisons for s[x:y:], 0 <= x <= y
193193
func goPanicSlice3C(x int, y int) {
194194
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
195-
panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSlice3C})
195+
panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsSlice3C})
196196
}
197197
func goPanicSlice3CU(x uint, y int) {
198198
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
199-
panic(boundsError{x: int64(x), signed: false, y: y, code: boundsSlice3C})
199+
panic(boundsError{x: int64(x), signed: false, y: y, code: abi.BoundsSlice3C})
200200
}
201201

202202
// failures in the conversion ([x]T)(s) or (*[x]T)(s), 0 <= x <= y, y == len(s)
203203
func goPanicSliceConvert(x int, y int) {
204204
panicCheck1(sys.GetCallerPC(), "slice length too short to convert to array or pointer to array")
205-
panic(boundsError{x: int64(x), signed: true, y: y, code: boundsConvert})
205+
panic(boundsError{x: int64(x), signed: true, y: y, code: abi.BoundsConvert})
206206
}
207207

208208
// Implemented in assembly, as they take arguments in registers.

src/runtime/panic32.go

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package runtime
88

99
import (
10+
"internal/abi"
1011
"internal/runtime/sys"
1112
)
1213

@@ -16,77 +17,77 @@ import (
1617
// failures in the comparisons for s[x], 0 <= x < y (y == len(s))
1718
func goPanicExtendIndex(hi int, lo uint, y int) {
1819
panicCheck1(sys.GetCallerPC(), "index out of range")
19-
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsIndex})
20+
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: abi.BoundsIndex})
2021
}
2122
func goPanicExtendIndexU(hi uint, lo uint, y int) {
2223
panicCheck1(sys.GetCallerPC(), "index out of range")
23-
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsIndex})
24+
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: abi.BoundsIndex})
2425
}
2526

2627
// failures in the comparisons for s[:x], 0 <= x <= y (y == len(s) or cap(s))
2728
func goPanicExtendSliceAlen(hi int, lo uint, y int) {
2829
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
29-
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsSliceAlen})
30+
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: abi.BoundsSliceAlen})
3031
}
3132
func goPanicExtendSliceAlenU(hi uint, lo uint, y int) {
3233
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
33-
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsSliceAlen})
34+
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: abi.BoundsSliceAlen})
3435
}
3536
func goPanicExtendSliceAcap(hi int, lo uint, y int) {
3637
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
37-
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsSliceAcap})
38+
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: abi.BoundsSliceAcap})
3839
}
3940
func goPanicExtendSliceAcapU(hi uint, lo uint, y int) {
4041
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
41-
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsSliceAcap})
42+
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: abi.BoundsSliceAcap})
4243
}
4344

4445
// failures in the comparisons for s[x:y], 0 <= x <= y
4546
func goPanicExtendSliceB(hi int, lo uint, y int) {
4647
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
47-
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsSliceB})
48+
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: abi.BoundsSliceB})
4849
}
4950
func goPanicExtendSliceBU(hi uint, lo uint, y int) {
5051
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
51-
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsSliceB})
52+
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: abi.BoundsSliceB})
5253
}
5354

5455
// failures in the comparisons for s[::x], 0 <= x <= y (y == len(s) or cap(s))
5556
func goPanicExtendSlice3Alen(hi int, lo uint, y int) {
5657
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
57-
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsSlice3Alen})
58+
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: abi.BoundsSlice3Alen})
5859
}
5960
func goPanicExtendSlice3AlenU(hi uint, lo uint, y int) {
6061
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
61-
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsSlice3Alen})
62+
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: abi.BoundsSlice3Alen})
6263
}
6364
func goPanicExtendSlice3Acap(hi int, lo uint, y int) {
6465
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
65-
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsSlice3Acap})
66+
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: abi.BoundsSlice3Acap})
6667
}
6768
func goPanicExtendSlice3AcapU(hi uint, lo uint, y int) {
6869
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
69-
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsSlice3Acap})
70+
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: abi.BoundsSlice3Acap})
7071
}
7172

7273
// failures in the comparisons for s[:x:y], 0 <= x <= y
7374
func goPanicExtendSlice3B(hi int, lo uint, y int) {
7475
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
75-
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsSlice3B})
76+
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: abi.BoundsSlice3B})
7677
}
7778
func goPanicExtendSlice3BU(hi uint, lo uint, y int) {
7879
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
79-
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsSlice3B})
80+
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: abi.BoundsSlice3B})
8081
}
8182

8283
// failures in the comparisons for s[x:y:], 0 <= x <= y
8384
func goPanicExtendSlice3C(hi int, lo uint, y int) {
8485
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
85-
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: boundsSlice3C})
86+
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: true, y: y, code: abi.BoundsSlice3C})
8687
}
8788
func goPanicExtendSlice3CU(hi uint, lo uint, y int) {
8889
panicCheck1(sys.GetCallerPC(), "slice bounds out of range")
89-
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: boundsSlice3C})
90+
panic(boundsError{x: int64(hi)<<32 + int64(lo), signed: false, y: y, code: abi.BoundsSlice3C})
9091
}
9192

9293
// Implemented in assembly, as they take arguments in registers.

0 commit comments

Comments
 (0)