From 2a4845257fea627da8b30444a498576ea90b5401 Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Sun, 5 Sep 2021 20:50:54 +0700 Subject: [PATCH] cmd/compile: fix deadlock in (*Named).load For lazy import resolution, there's reentrancy issue with (*Named).load method, when "t.resolve(t)" can lead us to the same named type, thus (*Named).load is called recursively, causing the deadlock. The main problem is that when instantinate a type, we calculate the type hashing, including TParams. Calling t.TParams().Len() triggers the reentrancy call to "(*Named).load". To fix this, just not checking TParams().Len() if we are hashing. Updates #48185 Change-Id: Ie34842d7b10fad5d11fbcf75bb1c64a89deac6b8 Reviewed-on: https://go-review.googlesource.com/c/go/+/347534 Trust: Cuong Manh Le Trust: Robert Griesemer Run-TryBot: Cuong Manh Le Reviewed-by: Matthew Dempsky Reviewed-by: Robert Findley Reviewed-by: Robert Griesemer TryBot-Result: Go Bot --- src/cmd/compile/internal/types2/typestring.go | 2 +- test/typeparam/issue48185a.dir/p.go | 19 +++++++++++++++++++ test/typeparam/issue48185a.dir/p_test.go | 11 +++++++++++ test/typeparam/issue48185a.go | 7 +++++++ 4 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 test/typeparam/issue48185a.dir/p.go create mode 100644 test/typeparam/issue48185a.dir/p_test.go create mode 100644 test/typeparam/issue48185a.go diff --git a/src/cmd/compile/internal/types2/typestring.go b/src/cmd/compile/internal/types2/typestring.go index da5de08758d..6083955306b 100644 --- a/src/cmd/compile/internal/types2/typestring.go +++ b/src/cmd/compile/internal/types2/typestring.go @@ -234,7 +234,7 @@ func (w *typeWriter) typ(typ Type) { if t.targs != nil { // instantiated type w.typeList(t.targs.list()) - } else if t.TParams().Len() != 0 { + } else if !w.hash && t.TParams().Len() != 0 { // For type hashing, don't need to format the TParams // parameterized type w.tParamList(t.TParams().list()) } diff --git a/test/typeparam/issue48185a.dir/p.go b/test/typeparam/issue48185a.dir/p.go new file mode 100644 index 00000000000..176c7f4de5c --- /dev/null +++ b/test/typeparam/issue48185a.dir/p.go @@ -0,0 +1,19 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package p + +type MarshalOptions struct { + Marshalers *Marshalers +} + +type Encoder struct {} + +type Marshalers = marshalers[MarshalOptions, Encoder] + +type marshalers[Options, Coder any] struct{} + +func MarshalFuncV1[T any](fn func(T) ([]byte, error)) *Marshalers { + return &Marshalers{} +} diff --git a/test/typeparam/issue48185a.dir/p_test.go b/test/typeparam/issue48185a.dir/p_test.go new file mode 100644 index 00000000000..52c87a7e297 --- /dev/null +++ b/test/typeparam/issue48185a.dir/p_test.go @@ -0,0 +1,11 @@ +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import "p" + +func main() { + _ = p.MarshalFuncV1[int](func(int) ([]byte, error) { return nil, nil }) +} diff --git a/test/typeparam/issue48185a.go b/test/typeparam/issue48185a.go new file mode 100644 index 00000000000..40df49f83be --- /dev/null +++ b/test/typeparam/issue48185a.go @@ -0,0 +1,7 @@ +// rundir + +// Copyright 2021 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ignored