From ddc93a536faf4576d182cd3197b116d61d05c484 Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Mon, 29 Aug 2022 17:25:32 +0700 Subject: cmd/compile: fix unified IR shapifying recursive instantiated types Shape-based stenciling in unified IR is done by converting type argument to its underlying type. So it agressively check that type argument is not a TFORW. However, for recursive instantiated type argument, it may still be a TFORW when shapifying happens. Thus the assertion failed, causing the compiler crashing. To fix it, just allow fully instantiated type when shapifying. Fixes #54512 Fixes #54722 Change-Id: I527e3fd696388c8a37454e738f0324f0c2ec16cb Reviewed-on: https://go-review.googlesource.com/c/go/+/426335 TryBot-Result: Gopher Robot Auto-Submit: Cuong Manh Le Run-TryBot: Cuong Manh Le Reviewed-by: Heschi Kreinick Reviewed-by: Matthew Dempsky --- src/cmd/compile/internal/noder/reader.go | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'src/cmd/compile/internal/noder/reader.go') diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go index d1a8843138..a34d5c924a 100644 --- a/src/cmd/compile/internal/noder/reader.go +++ b/src/cmd/compile/internal/noder/reader.go @@ -817,7 +817,22 @@ func (dict *readerDict) mangle(sym *types.Sym) *types.Sym { // If basic is true, then the type argument is used to instantiate a // type parameter whose constraint is a basic interface. func shapify(targ *types.Type, basic bool) *types.Type { - base.Assertf(targ.Kind() != types.TFORW, "%v is missing its underlying type", targ) + if targ.Kind() == types.TFORW { + if targ.IsFullyInstantiated() { + // For recursive instantiated type argument, it may still be a TFORW + // when shapifying happens. If we don't have targ's underlying type, + // shapify won't work. The worst case is we end up not reusing code + // optimally in some tricky cases. + if base.Debug.Shapify != 0 { + base.Warn("skipping shaping of recursive type %v", targ) + } + if targ.HasShape() { + return targ + } + } else { + base.Fatalf("%v is missing its underlying type", targ) + } + } // When a pointer type is used to instantiate a type parameter // constrained by a basic interface, we know the pointer's element -- cgit v1.3-5-g9baa