cmd/compile: add marker for skipping dowidth when tracing typecheck

The root cause of #33658 is that fmt.Printf does have side effects when
printing Type.

typefmt for TINTER will call Type.Fields to get all embedded fields and
methods. The thing is that type.Fields itself will call dowidth, which will
expand the embedded interface, make it non-embedded anymore.

To fix it, we add a marker while we are tracing, so dowidth can know and
return immediately without doing anything.

Fixes #33658

Change-Id: Id4b70ff68a3b802675deae96793fdb8f7ef1a4a7
Reviewed-on: https://go-review.googlesource.com/c/go/+/190537
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
LE Manh Cuong 2019-08-16 16:05:10 +07:00 коммит произвёл Matthew Dempsky
Родитель 5eec0a91ea
Коммит 3db6d46a4e
2 изменённых файлов: 10 добавлений и 0 удалений

Просмотреть файл

@ -178,6 +178,11 @@ func widstruct(errtype *types.Type, t *types.Type, o int64, flag int) int64 {
// have not already been calculated, it calls Fatal.
// This is used to prevent data races in the back end.
func dowidth(t *types.Type) {
// Calling dowidth when typecheck tracing enabled is not safe.
// See issue #33658.
if enableTrace && skipDowidthForTracing {
return
}
if Widthptr == 0 {
Fatalf("dowidth without betypeinit")
}

Просмотреть файл

@ -16,6 +16,7 @@ const enableTrace = false
var trace bool
var traceIndent []byte
var skipDowidthForTracing bool
func tracePrint(title string, n *Node) func(np **Node) {
indent := traceIndent
@ -29,6 +30,8 @@ func tracePrint(title string, n *Node) func(np **Node) {
tc = n.Typecheck()
}
skipDowidthForTracing = true
defer func() { skipDowidthForTracing = false }()
fmt.Printf("%s: %s%s %p %s %v tc=%d\n", pos, indent, title, n, op, n, tc)
traceIndent = append(traceIndent, ". "...)
@ -51,6 +54,8 @@ func tracePrint(title string, n *Node) func(np **Node) {
typ = n.Type
}
skipDowidthForTracing = true
defer func() { skipDowidthForTracing = false }()
fmt.Printf("%s: %s=> %p %s %v tc=%d type=%#L\n", pos, indent, n, op, n, tc, typ)
}
}