aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2025-11-24 15:00:11 -0500
committerDavid Chase <drchase@google.com>2025-11-24 15:49:12 -0800
commit62cd044a79b9f2ba889bca59b3b12400dc41dd85 (patch)
treea120624e15b2a31014cc6e215a48cefbecf3fe99 /src/cmd/compile
parentf1e376f342af82d6f5bdba23cdc5c35b5bfd9064 (diff)
downloadgo-62cd044a79b9f2ba889bca59b3b12400dc41dd85.tar.xz
cmd/compile: add cases for StringLen to prove
Tricky index-offset logic had been added for slices, but not for strings. This fixes that, and also adds tests for same behavior in string/slice cases, and adds a new test for code in prove that had been added but not explicitly tested. Fixes #76270. Change-Id: Ibd92b89e944d86b7f30b4486a9008e6f1ac6af7d Reviewed-on: https://go-review.googlesource.com/c/go/+/723980 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/cmd/compile')
-rw-r--r--src/cmd/compile/internal/ssa/prove.go14
1 files changed, 7 insertions, 7 deletions
diff --git a/src/cmd/compile/internal/ssa/prove.go b/src/cmd/compile/internal/ssa/prove.go
index 5581da445d..536965a0a0 100644
--- a/src/cmd/compile/internal/ssa/prove.go
+++ b/src/cmd/compile/internal/ssa/prove.go
@@ -2040,14 +2040,14 @@ func (ft *factsTable) flowLimit(v *Value) {
//
// slicecap - index >= slicelen - index >= K
//
-// Note that "index" is not useed for indexing in this pattern, but
+// Note that "index" is not used for indexing in this pattern, but
// in the motivating example (chunked slice iteration) it is.
func (ft *factsTable) detectSliceLenRelation(v *Value) {
if v.Op != OpSub64 {
return
}
- if !(v.Args[0].Op == OpSliceLen || v.Args[0].Op == OpSliceCap) {
+ if !(v.Args[0].Op == OpSliceLen || v.Args[0].Op == OpStringLen || v.Args[0].Op == OpSliceCap) {
return
}
@@ -2070,9 +2070,9 @@ func (ft *factsTable) detectSliceLenRelation(v *Value) {
continue
}
var lenOffset *Value
- if bound := ow.Args[0]; bound.Op == OpSliceLen && bound.Args[0] == slice {
+ if bound := ow.Args[0]; (bound.Op == OpSliceLen || bound.Op == OpStringLen) && bound.Args[0] == slice {
lenOffset = ow.Args[1]
- } else if bound := ow.Args[1]; bound.Op == OpSliceLen && bound.Args[0] == slice {
+ } else if bound := ow.Args[1]; (bound.Op == OpSliceLen || bound.Op == OpStringLen) && bound.Args[0] == slice {
lenOffset = ow.Args[0]
}
if lenOffset == nil || lenOffset.Op != OpConst64 {
@@ -2332,7 +2332,7 @@ func unsignedSubUnderflows(a, b uint64) bool {
// iteration where the index is not directly compared to the length.
// if isReslice, then delta can be equal to K.
func checkForChunkedIndexBounds(ft *factsTable, b *Block, index, bound *Value, isReslice bool) bool {
- if bound.Op != OpSliceLen && bound.Op != OpSliceCap {
+ if bound.Op != OpSliceLen && bound.Op != OpStringLen && bound.Op != OpSliceCap {
return false
}
@@ -2367,9 +2367,9 @@ func checkForChunkedIndexBounds(ft *factsTable, b *Block, index, bound *Value, i
}
if ow := o.w; ow.Op == OpAdd64 {
var lenOffset *Value
- if bound := ow.Args[0]; bound.Op == OpSliceLen && bound.Args[0] == slice {
+ if bound := ow.Args[0]; (bound.Op == OpSliceLen || bound.Op == OpStringLen) && bound.Args[0] == slice {
lenOffset = ow.Args[1]
- } else if bound := ow.Args[1]; bound.Op == OpSliceLen && bound.Args[0] == slice {
+ } else if bound := ow.Args[1]; (bound.Op == OpSliceLen || bound.Op == OpStringLen) && bound.Args[0] == slice {
lenOffset = ow.Args[0]
}
if lenOffset == nil || lenOffset.Op != OpConst64 {