aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssagen
diff options
context:
space:
mode:
authorCherry Mui <cherryyz@google.com>2021-07-14 18:52:44 -0400
committerCherry Mui <cherryyz@google.com>2021-07-19 18:00:46 +0000
commit404127c30f3f66eb234da2dc1a78e6eea0ef4ee0 (patch)
treefb846d3500b168872b95530986bb8a6a5811f109 /src/cmd/compile/internal/ssagen
parent6298cfe6724e3ca24dedd3f62b2b358aafe17276 (diff)
downloadgo-404127c30f3f66eb234da2dc1a78e6eea0ef4ee0.tar.gz
go-404127c30f3f66eb234da2dc1a78e6eea0ef4ee0.zip
cmd/compile: fix off-by-one error in traceback argument counting
For traceback argument printing, we want to print at most 10 words, then print "..." if there are still more args and/or fields. The current code has off-by-one error that for 11 non-aggregate typed args, it prints the first 10 but without the "...". Also, for aggregate-typed args, in some cases it may print an extra "..." when there is actually no more fields. The problem for this is that visitType return false (meaning not to continue visiting) if it reaches the limit anywhere during the recursive visit. It doesn't distinguish whether it has printed anything for the current arg. If it reaches the limit before it prints anything, it means that we're visiting the extra arg/field, so the caller should print "..." and stop. If it prints something then reaches the limit, however, the caller should keep going, and only print "..." at the next iteration when there is actually an extra arg/field. This CL does so. Fixes #47159. Change-Id: I93fc25b73ada2b5a98df780c45e5b0c9565dc2fc Reviewed-on: https://go-review.googlesource.com/c/go/+/334710 Trust: Cherry Mui <cherryyz@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssagen')
-rw-r--r--src/cmd/compile/internal/ssagen/ssa.go43
1 files changed, 15 insertions, 28 deletions
diff --git a/src/cmd/compile/internal/ssagen/ssa.go b/src/cmd/compile/internal/ssagen/ssa.go
index f1dc56e729..a5cb0857b3 100644
--- a/src/cmd/compile/internal/ssagen/ssa.go
+++ b/src/cmd/compile/internal/ssagen/ssa.go
@@ -6598,6 +6598,7 @@ func EmitArgInfo(f *ir.Func, abiInfo *abi.ABIParamResultInfo) *obj.LSym {
x := base.Ctxt.Lookup(fmt.Sprintf("%s.arginfo%d", f.LSym.Name, f.ABI))
PtrSize := int64(types.PtrSize)
+ uintptrTyp := types.Types[types.TUINTPTR]
isAggregate := func(t *types.Type) bool {
return t.IsStruct() || t.IsArray() || t.IsComplex() || t.IsInterface() || t.IsString() || t.IsSlice()
@@ -6641,12 +6642,8 @@ 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 if there is room.
- // Returns whether to continue.
- write1 := func(sz, offset int64) bool {
- if n >= limit {
- return false
- }
+ // Write one non-aggrgate arg/field/element.
+ write1 := func(sz, offset int64) {
if offset >= _special {
writebyte(_offsetTooLarge)
} else {
@@ -6654,7 +6651,6 @@ func EmitArgInfo(f *ir.Func, abiInfo *abi.ABIParamResultInfo) *obj.LSym {
writebyte(uint8(sz))
}
n++
- return true
}
// Visit t recursively and write it out.
@@ -6662,10 +6658,12 @@ func EmitArgInfo(f *ir.Func, abiInfo *abi.ABIParamResultInfo) *obj.LSym {
var visitType func(baseOffset int64, t *types.Type, depth int) bool
visitType = func(baseOffset int64, t *types.Type, depth int) bool {
if n >= limit {
+ writebyte(_dotdotdot)
return false
}
if !isAggregate(t) {
- return write1(t.Size(), baseOffset)
+ write1(t.Size(), baseOffset)
+ return true
}
writebyte(_startAgg)
depth++
@@ -6675,58 +6673,47 @@ func EmitArgInfo(f *ir.Func, abiInfo *abi.ABIParamResultInfo) *obj.LSym {
n++
return true
}
- var r bool
switch {
case t.IsInterface(), t.IsString():
- r = write1(PtrSize, baseOffset) &&
- write1(PtrSize, baseOffset+PtrSize)
+ _ = visitType(baseOffset, uintptrTyp, depth) &&
+ visitType(baseOffset+PtrSize, uintptrTyp, depth)
case t.IsSlice():
- r = write1(PtrSize, baseOffset) &&
- write1(PtrSize, baseOffset+PtrSize) &&
- write1(PtrSize, baseOffset+PtrSize*2)
+ _ = visitType(baseOffset, uintptrTyp, depth) &&
+ visitType(baseOffset+PtrSize, uintptrTyp, depth) &&
+ visitType(baseOffset+PtrSize*2, uintptrTyp, depth)
case t.IsComplex():
- r = write1(t.Size()/2, baseOffset) &&
- write1(t.Size()/2, baseOffset+t.Size()/2)
+ _ = visitType(baseOffset, types.FloatForComplex(t), depth) &&
+ visitType(baseOffset+t.Size()/2, types.FloatForComplex(t), depth)
case t.IsArray():
- r = true
if t.NumElem() == 0 {
n++ // {} counts as a component
break
}
for i := int64(0); i < t.NumElem(); i++ {
if !visitType(baseOffset, t.Elem(), depth) {
- r = false
break
}
baseOffset += t.Elem().Size()
}
case t.IsStruct():
- r = true
if t.NumFields() == 0 {
n++ // {} counts as a component
break
}
for _, field := range t.Fields().Slice() {
if !visitType(baseOffset+field.Offset, field.Type, depth) {
- r = false
break
}
}
}
- if !r {
- writebyte(_dotdotdot)
- }
writebyte(_endAgg)
- return r
+ return true
}
- c := true
for _, a := range abiInfo.InParams() {
- if !c {
- writebyte(_dotdotdot)
+ if !visitType(a.FrameOffset(abiInfo), a.Type, 0) {
break
}
- c = visitType(a.FrameOffset(abiInfo), a.Type, 0)
}
writebyte(_endSeq)
if wOff > maxLen {