зеркало из https://github.com/CryptoPro/go.git
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:
Родитель
5eec0a91ea
Коммит
3db6d46a4e
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче