]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: use correct type for slice pointer
authorKeith Randall <khr@golang.org>
Tue, 28 Nov 2023 01:21:08 +0000 (17:21 -0800)
committerKeith Randall <khr@google.com>
Tue, 28 Nov 2023 05:13:40 +0000 (05:13 +0000)
The type of the data pointer field of a slice should be a pointer
to the element type, not a *uint8.

This ensures that the SSA value representing the slice's data pointer
can be spilled to the stack slot for the corresponding argument.
Before this change the types didn't match so we ended up spilling the
argument to an autotmp instead of to the dedicated argument slot.

Fixes #64414

Change-Id: I09ee39e93f05aee07e3eceb14e39736d7fd70a33
Reviewed-on: https://go-review.googlesource.com/c/go/+/545357
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/ssa/expand_calls.go
src/cmd/compile/internal/ssagen/ssa.go
src/runtime/traceback_test.go

index 298e29ec56d6f98c0796b526c8d7fab3d751a40d..b0788f1db4bba556b05f93d36705b90f2c975f09 100644 (file)
@@ -411,7 +411,7 @@ func (x *expandState) decomposeAsNecessary(pos src.XPos, b *Block, a, m0 *Value,
                return mem
 
        case types.TSLICE:
-               mem = x.decomposeOne(pos, b, a, mem, x.typs.BytePtr, OpSlicePtr, &rc)
+               mem = x.decomposeOne(pos, b, a, mem, at.Elem().PtrTo(), OpSlicePtr, &rc)
                pos = pos.WithNotStmt()
                mem = x.decomposeOne(pos, b, a, mem, x.typs.Int, OpSliceLen, &rc)
                return x.decomposeOne(pos, b, a, mem, x.typs.Int, OpSliceCap, &rc)
@@ -564,7 +564,7 @@ func (x *expandState) rewriteSelectOrArg(pos src.XPos, b *Block, container, a, m
                return a
 
        case types.TSLICE:
-               addArg(x.rewriteSelectOrArg(pos, b, container, nil, m0, x.typs.BytePtr, rc.next(x.typs.BytePtr)))
+               addArg(x.rewriteSelectOrArg(pos, b, container, nil, m0, at.Elem().PtrTo(), rc.next(x.typs.BytePtr)))
                pos = pos.WithNotStmt()
                addArg(x.rewriteSelectOrArg(pos, b, container, nil, m0, x.typs.Int, rc.next(x.typs.Int)))
                addArg(x.rewriteSelectOrArg(pos, b, container, nil, m0, x.typs.Int, rc.next(x.typs.Int)))
@@ -721,7 +721,7 @@ func (x *expandState) rewriteWideSelectToStores(pos src.XPos, b *Block, containe
                return m0
 
        case types.TSLICE:
-               m0 = x.rewriteWideSelectToStores(pos, b, container, m0, x.typs.BytePtr, rc.next(x.typs.BytePtr))
+               m0 = x.rewriteWideSelectToStores(pos, b, container, m0, at.Elem().PtrTo(), rc.next(x.typs.BytePtr))
                pos = pos.WithNotStmt()
                m0 = x.rewriteWideSelectToStores(pos, b, container, m0, x.typs.Int, rc.next(x.typs.Int))
                m0 = x.rewriteWideSelectToStores(pos, b, container, m0, x.typs.Int, rc.next(x.typs.Int))
index 45bf0e6dc438a4025f34acf66447ed6343cafd16..c794d6ffd9d783da2e63ba89e39cb1051b0ae66d 100644 (file)
@@ -7133,7 +7133,7 @@ func EmitArgInfo(f *ir.Func, abiInfo *abi.ABIParamResultInfo) *obj.LSym {
        n := 0
        writebyte := func(o uint8) { wOff = objw.Uint8(x, wOff, o) }
 
-       // Write one non-aggrgate arg/field/element.
+       // Write one non-aggregate arg/field/element.
        write1 := func(sz, offset int64) {
                if offset >= _special {
                        writebyte(_offsetTooLarge)
index 204b4f5316c99d653a85fa62ae303b42351855d7..88318782da02fd5d5509363805af77a421cd5a7a 100644 (file)
@@ -419,6 +419,17 @@ func TestTracebackArgs(t *testing.T) {
                                "testTracebackArgs11b(0xffffffff?, 0xffffffff?, 0x3?, 0x4)",
                                "testTracebackArgs11b(0x1, 0x2, 0x3, 0x4)"),
                },
+               // Make sure spilled slice data pointers are spilled to the right location
+               // to ensure we see it listed without a ?.
+               // See issue 64414.
+               {
+                       func() int {
+                               poisonStack()
+                               return testTracebackArgsSlice(testTracebackArgsSliceBackingStore[:])
+                       },
+                       // Note: capacity of the slice might be junk, as it is not used.
+                       fmt.Sprintf("testTracebackArgsSlice({%p, 0x2, ", &testTracebackArgsSliceBackingStore[0]),
+               },
        }
        for _, test := range tests {
                n := test.fn()
@@ -667,6 +678,19 @@ func testTracebackArgs11b(a, b, c, d int32) int {
        return runtime.Stack(testTracebackArgsBuf[:], false)
 }
 
+// norace to avoid race instrumentation changing spill locations.
+// nosplit to avoid preemption or morestack spilling registers.
+//
+//go:norace
+//go:nosplit
+//go:noinline
+func testTracebackArgsSlice(a []int) int {
+       n := runtime.Stack(testTracebackArgsBuf[:], false)
+       return a[1] + n
+}
+
+var testTracebackArgsSliceBackingStore [2]int
+
 // Poison the arg area with deterministic values.
 //
 //go:noinline