Skip to content

Commit 46410b7

Browse files
committed
cmd/compile: use correct type for slice pointer
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 <[email protected]> Reviewed-by: Keith Randall <[email protected]> Reviewed-by: David Chase <[email protected]>
1 parent 4956c34 commit 46410b7

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

src/cmd/compile/internal/ssa/expand_calls.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,7 @@ func (x *expandState) decomposeAsNecessary(pos src.XPos, b *Block, a, m0 *Value,
411411
return mem
412412

413413
case types.TSLICE:
414-
mem = x.decomposeOne(pos, b, a, mem, x.typs.BytePtr, OpSlicePtr, &rc)
414+
mem = x.decomposeOne(pos, b, a, mem, at.Elem().PtrTo(), OpSlicePtr, &rc)
415415
pos = pos.WithNotStmt()
416416
mem = x.decomposeOne(pos, b, a, mem, x.typs.Int, OpSliceLen, &rc)
417417
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
564564
return a
565565

566566
case types.TSLICE:
567-
addArg(x.rewriteSelectOrArg(pos, b, container, nil, m0, x.typs.BytePtr, rc.next(x.typs.BytePtr)))
567+
addArg(x.rewriteSelectOrArg(pos, b, container, nil, m0, at.Elem().PtrTo(), rc.next(x.typs.BytePtr)))
568568
pos = pos.WithNotStmt()
569569
addArg(x.rewriteSelectOrArg(pos, b, container, nil, m0, x.typs.Int, rc.next(x.typs.Int)))
570570
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
721721
return m0
722722

723723
case types.TSLICE:
724-
m0 = x.rewriteWideSelectToStores(pos, b, container, m0, x.typs.BytePtr, rc.next(x.typs.BytePtr))
724+
m0 = x.rewriteWideSelectToStores(pos, b, container, m0, at.Elem().PtrTo(), rc.next(x.typs.BytePtr))
725725
pos = pos.WithNotStmt()
726726
m0 = x.rewriteWideSelectToStores(pos, b, container, m0, x.typs.Int, rc.next(x.typs.Int))
727727
m0 = x.rewriteWideSelectToStores(pos, b, container, m0, x.typs.Int, rc.next(x.typs.Int))

src/cmd/compile/internal/ssagen/ssa.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7133,7 +7133,7 @@ func EmitArgInfo(f *ir.Func, abiInfo *abi.ABIParamResultInfo) *obj.LSym {
71337133
n := 0
71347134
writebyte := func(o uint8) { wOff = objw.Uint8(x, wOff, o) }
71357135

7136-
// Write one non-aggrgate arg/field/element.
7136+
// Write one non-aggregate arg/field/element.
71377137
write1 := func(sz, offset int64) {
71387138
if offset >= _special {
71397139
writebyte(_offsetTooLarge)

src/runtime/traceback_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,17 @@ func TestTracebackArgs(t *testing.T) {
419419
"testTracebackArgs11b(0xffffffff?, 0xffffffff?, 0x3?, 0x4)",
420420
"testTracebackArgs11b(0x1, 0x2, 0x3, 0x4)"),
421421
},
422+
// Make sure spilled slice data pointers are spilled to the right location
423+
// to ensure we see it listed without a ?.
424+
// See issue 64414.
425+
{
426+
func() int {
427+
poisonStack()
428+
return testTracebackArgsSlice(testTracebackArgsSliceBackingStore[:])
429+
},
430+
// Note: capacity of the slice might be junk, as it is not used.
431+
fmt.Sprintf("testTracebackArgsSlice({%p, 0x2, ", &testTracebackArgsSliceBackingStore[0]),
432+
},
422433
}
423434
for _, test := range tests {
424435
n := test.fn()
@@ -667,6 +678,19 @@ func testTracebackArgs11b(a, b, c, d int32) int {
667678
return runtime.Stack(testTracebackArgsBuf[:], false)
668679
}
669680

681+
// norace to avoid race instrumentation changing spill locations.
682+
// nosplit to avoid preemption or morestack spilling registers.
683+
//
684+
//go:norace
685+
//go:nosplit
686+
//go:noinline
687+
func testTracebackArgsSlice(a []int) int {
688+
n := runtime.Stack(testTracebackArgsBuf[:], false)
689+
return a[1] + n
690+
}
691+
692+
var testTracebackArgsSliceBackingStore [2]int
693+
670694
// Poison the arg area with deterministic values.
671695
//
672696
//go:noinline

0 commit comments

Comments
 (0)