diff options
author | Dan Scales <danscales@google.com> | 2021-08-24 15:34:52 -0700 |
---|---|---|
committer | Dan Scales <danscales@google.com> | 2021-08-25 15:30:19 +0000 |
commit | 099b819085e12ca45ac184cab5afb82538bec472 (patch) | |
tree | b580d10b26a2e3060acc4c5572756e036022f92a /src/cmd/compile/internal/noder | |
parent | e1fcf8857e1b3e076cc3a6fad1860afe0d6c2ca6 (diff) | |
download | go-099b819085e12ca45ac184cab5afb82538bec472.tar.gz go-099b819085e12ca45ac184cab5afb82538bec472.zip |
cmd/compile: fix CheckSize() calculation for -G=3 and stencils
Because the Align/Width of pointer types are always set when created,
CalcSize() never descends past a pointer. Therefore, we need to do
CheckSize() at every level when creating type. We need to do this for
types creates by types2-to-types1 conversion and also by type
substitution (mostly for stenciling). We also need to do
Defer/ResumeCheckSize() at the top level in each of these cases to deal
with potentially recursive types.
These changes fix issue #47929 and also allow us to remove the
special-case CheckSize() call that causes the problem for issue #47901.
Fixes #47901
Fixes #47929
Change-Id: Icd8192431c145009cd6df2f4ade6db7da0f4dd3e
Reviewed-on: https://go-review.googlesource.com/c/go/+/344829
Trust: Dan Scales <danscales@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/noder')
-rw-r--r-- | src/cmd/compile/internal/noder/types.go | 24 |
1 files changed, 10 insertions, 14 deletions
diff --git a/src/cmd/compile/internal/noder/types.go b/src/cmd/compile/internal/noder/types.go index 541ed68ef3..c9f7c2bbe4 100644 --- a/src/cmd/compile/internal/noder/types.go +++ b/src/cmd/compile/internal/noder/types.go @@ -30,21 +30,11 @@ func (g *irgen) pkg(pkg *types2.Package) *types.Pkg { // typ converts a types2.Type to a types.Type, including caching of previously // translated types. func (g *irgen) typ(typ types2.Type) *types.Type { + // Defer the CheckSize calls until we have fully-defined a + // (possibly-recursive) top-level type. + types.DeferCheckSize() res := g.typ1(typ) - - // Calculate the size for all concrete types seen by the frontend. The old - // typechecker calls CheckSize() a lot, and we want to eliminate calling - // it eventually, so we should do it here instead. We only call it for - // top-level types (i.e. we do it here rather in typ1), to make sure that - // recursive types have been fully constructed before we call CheckSize. - if res != nil && !res.IsUntyped() && !res.IsFuncArgStruct() && !res.HasTParam() { - types.CheckSize(res) - if res.IsPtr() { - // Pointers always have their size set, even though their element - // may not have its size set. - types.CheckSize(res.Elem()) - } - } + types.ResumeCheckSize() return res } @@ -59,6 +49,12 @@ func (g *irgen) typ1(typ types2.Type) *types.Type { res, ok := g.typs[typ] if !ok { res = g.typ0(typ) + // Calculate the size for all concrete types seen by the frontend. + // This is the replacement for the CheckSize() calls in the types1 + // typechecker. These will be deferred until the top-level g.typ(). + if res != nil && !res.IsUntyped() && !res.IsFuncArgStruct() && !res.HasTParam() { + types.CheckSize(res) + } g.typs[typ] = res } return res |