diff options
author | Josh Bleecher Snyder <josharian@gmail.com> | 2021-03-14 14:24:47 -0700 |
---|---|---|
committer | Josh Bleecher Snyder <josharian@gmail.com> | 2021-04-21 00:53:48 +0000 |
commit | faa4fa1a6e94fce4f6fa22524a2bece5125213b6 (patch) | |
tree | ecd5c4b860564b5b1926725f6ffafcebfac3b3d9 /src/cmd/compile/internal/ssa | |
parent | 1c268431f49ee2fc843eac52a0854aea3d02a6e0 (diff) | |
download | go-faa4fa1a6e94fce4f6fa22524a2bece5125213b6.tar.gz go-faa4fa1a6e94fce4f6fa22524a2bece5125213b6.zip |
cmd/compile: allow conversion from slice to array ptr
Panic if the slice is too short.
Updates #395
Change-Id: I90f4bff2da5d8f3148ba06d2482084f32b25c29a
Reviewed-on: https://go-review.googlesource.com/c/go/+/301650
Trust: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa')
-rw-r--r-- | src/cmd/compile/internal/ssa/expand_calls.go | 4 | ||||
-rw-r--r-- | src/cmd/compile/internal/ssa/gen/dec.rules | 1 | ||||
-rw-r--r-- | src/cmd/compile/internal/ssa/gen/genericOps.go | 4 | ||||
-rw-r--r-- | src/cmd/compile/internal/ssa/op.go | 4 | ||||
-rw-r--r-- | src/cmd/compile/internal/ssa/opGen.go | 6 | ||||
-rw-r--r-- | src/cmd/compile/internal/ssa/rewritedec.go | 16 |
6 files changed, 32 insertions, 3 deletions
diff --git a/src/cmd/compile/internal/ssa/expand_calls.go b/src/cmd/compile/internal/ssa/expand_calls.go index be460457a8..46c2388e7b 100644 --- a/src/cmd/compile/internal/ssa/expand_calls.go +++ b/src/cmd/compile/internal/ssa/expand_calls.go @@ -508,7 +508,7 @@ func (x *expandState) rewriteSelect(leaf *Value, selector *Value, offset int64, ls := x.rewriteSelect(leaf, selector.Args[0], offset, regOffset) locs = x.splitSlots(ls, ".ptr", 0, x.typs.BytePtr) - case OpSlicePtr: + case OpSlicePtr, OpSlicePtrUnchecked: w := selector.Args[0] ls := x.rewriteSelect(leaf, w, offset, regOffset) locs = x.splitSlots(ls, ".ptr", 0, types.NewPtr(w.Type.Elem())) @@ -1202,7 +1202,7 @@ func expandCalls(f *Func) { case OpStructSelect, OpArraySelect, OpIData, OpITab, OpStringPtr, OpStringLen, - OpSlicePtr, OpSliceLen, OpSliceCap, + OpSlicePtr, OpSliceLen, OpSliceCap, OpSlicePtrUnchecked, OpComplexReal, OpComplexImag, OpInt64Hi, OpInt64Lo: w := v.Args[0] diff --git a/src/cmd/compile/internal/ssa/gen/dec.rules b/src/cmd/compile/internal/ssa/gen/dec.rules index 4c677f8418..b19489870d 100644 --- a/src/cmd/compile/internal/ssa/gen/dec.rules +++ b/src/cmd/compile/internal/ssa/gen/dec.rules @@ -56,6 +56,7 @@ (SlicePtr (SliceMake ptr _ _ )) => ptr (SliceLen (SliceMake _ len _)) => len (SliceCap (SliceMake _ _ cap)) => cap +(SlicePtrUnchecked (SliceMake ptr _ _ )) => ptr (Load <t> ptr mem) && t.IsSlice() => (SliceMake diff --git a/src/cmd/compile/internal/ssa/gen/genericOps.go b/src/cmd/compile/internal/ssa/gen/genericOps.go index c38d22e07f..9f6664386c 100644 --- a/src/cmd/compile/internal/ssa/gen/genericOps.go +++ b/src/cmd/compile/internal/ssa/gen/genericOps.go @@ -479,6 +479,10 @@ var genericOps = []opData{ {name: "SlicePtr", argLength: 1, typ: "BytePtr"}, // ptr(arg0) {name: "SliceLen", argLength: 1}, // len(arg0) {name: "SliceCap", argLength: 1}, // cap(arg0) + // SlicePtrUnchecked, like SlicePtr, extracts the pointer from a slice. + // SlicePtr values are assumed non-nil, because they are guarded by bounds checks. + // SlicePtrUnchecked values can be nil. + {name: "SlicePtrUnchecked", argLength: 1}, // Complex (part/whole) {name: "ComplexMake", argLength: 2}, // arg0=real, arg1=imag diff --git a/src/cmd/compile/internal/ssa/op.go b/src/cmd/compile/internal/ssa/op.go index b99a7a6646..f09a08abcf 100644 --- a/src/cmd/compile/internal/ssa/op.go +++ b/src/cmd/compile/internal/ssa/op.go @@ -469,6 +469,7 @@ const ( BoundsSlice3BU // ... with unsigned high BoundsSlice3C // 3-arg slicing operation, 0 <= low <= high failed BoundsSlice3CU // ... with unsigned low + BoundsConvert // conversion to array pointer failed BoundsKindCount ) @@ -496,7 +497,8 @@ func boundsABI(b int64) int { case BoundsSlice3Alen, BoundsSlice3AlenU, BoundsSlice3Acap, - BoundsSlice3AcapU: + BoundsSlice3AcapU, + BoundsConvert: return 0 case BoundsSliceAlen, BoundsSliceAlenU, diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index 8c753ea2a3..2f56625397 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -2834,6 +2834,7 @@ const ( OpSlicePtr OpSliceLen OpSliceCap + OpSlicePtrUnchecked OpComplexMake OpComplexReal OpComplexImag @@ -35899,6 +35900,11 @@ var opcodeTable = [...]opInfo{ generic: true, }, { + name: "SlicePtrUnchecked", + argLen: 1, + generic: true, + }, + { name: "ComplexMake", argLen: 2, generic: true, diff --git a/src/cmd/compile/internal/ssa/rewritedec.go b/src/cmd/compile/internal/ssa/rewritedec.go index 4b7db60551..2a73a5ddc8 100644 --- a/src/cmd/compile/internal/ssa/rewritedec.go +++ b/src/cmd/compile/internal/ssa/rewritedec.go @@ -23,6 +23,8 @@ func rewriteValuedec(v *Value) bool { return rewriteValuedec_OpSliceLen(v) case OpSlicePtr: return rewriteValuedec_OpSlicePtr(v) + case OpSlicePtrUnchecked: + return rewriteValuedec_OpSlicePtrUnchecked(v) case OpStore: return rewriteValuedec_OpStore(v) case OpStringLen: @@ -248,6 +250,20 @@ func rewriteValuedec_OpSlicePtr(v *Value) bool { } return false } +func rewriteValuedec_OpSlicePtrUnchecked(v *Value) bool { + v_0 := v.Args[0] + // match: (SlicePtrUnchecked (SliceMake ptr _ _ )) + // result: ptr + for { + if v_0.Op != OpSliceMake { + break + } + ptr := v_0.Args[0] + v.copyOf(ptr) + return true + } + return false +} func rewriteValuedec_OpStore(v *Value) bool { v_2 := v.Args[2] v_1 := v.Args[1] |