]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: add marker for skipping dowidth when tracing typecheck
authorLE Manh Cuong <cuong.manhle.vn@gmail.com>
Fri, 16 Aug 2019 09:05:10 +0000 (16:05 +0700)
committerMatthew Dempsky <mdempsky@google.com>
Tue, 22 Oct 2019 18:26:35 +0000 (18:26 +0000)
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>
src/cmd/compile/internal/gc/align.go
src/cmd/compile/internal/gc/typecheck.go

index a2b5b53740806205e626abe49039c1b163cb61ef..44a06fd72781926f13b5c0360938231ad749382d 100644 (file)
@@ -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")
        }
index d2ad2f04f010d5a6d57c612431bd728d6807d704..140acb90627f42cf1b5352cb77c0fab4288c94bf 100644 (file)
@@ -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)
        }
 }