mirror of
https://github.com/golang/go.git
synced 2026-06-27 19:30:52 +00:00
cmd/compile: fix corner case boundedness for oversized shifts
For unsigned x >> k where k exceeds the width of x, the result is zero, which means that using it as an index doesn't require a bounds check...but not if the length is zero. Walk mishandled this. Fix it. It's a corner case, but the fix is trivial. Change-Id: Ieb7f2d33563f09e98bb31eefb2d2c01f03064311 Reviewed-on: https://go-review.googlesource.com/c/go/+/778200 Reviewed-by: Keith Randall <khr@google.com> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
8f7f951965
commit
0c3b9f837d
2 changed files with 29 additions and 2 deletions
|
|
@ -1015,7 +1015,7 @@ func walkStringHeader(n *ir.StringHeaderExpr, init *ir.Nodes) ir.Node {
|
|||
return n
|
||||
}
|
||||
|
||||
// return 1 if integer n must be in range [0, max), 0 otherwise.
|
||||
// bounded reports whether integer n must be in range [0, max).
|
||||
func bounded(n ir.Node, max int64) bool {
|
||||
if n.Type() == nil || !n.Type().IsInteger() {
|
||||
return false
|
||||
|
|
@ -1073,7 +1073,7 @@ func bounded(n ir.Node, max int64) bool {
|
|||
if !sign && ir.IsSmallIntConst(n.Y) {
|
||||
v := ir.Int64Val(n.Y)
|
||||
if v > int64(bits) {
|
||||
return true
|
||||
return max > 0
|
||||
}
|
||||
bits -= int32(v)
|
||||
}
|
||||
|
|
|
|||
27
test/fixedbugs/walk_bounded_overshift_empty_bound.go
Normal file
27
test/fixedbugs/walk_bounded_overshift_empty_bound.go
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
// run
|
||||
|
||||
// Copyright 2026 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.
|
||||
|
||||
package main
|
||||
|
||||
import "strings"
|
||||
|
||||
//go:noinline
|
||||
func f(i uint8) byte {
|
||||
return ""[i>>9]
|
||||
}
|
||||
|
||||
func main() {
|
||||
defer func() {
|
||||
r := recover()
|
||||
if r == nil {
|
||||
panic("missing bounds panic")
|
||||
}
|
||||
if got := r.(error).Error(); !strings.Contains(got, "index out of range") {
|
||||
panic(got)
|
||||
}
|
||||
}()
|
||||
_ = f(7)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue