aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/noder
diff options
context:
space:
mode:
authorDan Scales <danscales@google.com>2021-08-24 15:34:52 -0700
committerDan Scales <danscales@google.com>2021-08-25 15:30:19 +0000
commit099b819085e12ca45ac184cab5afb82538bec472 (patch)
treeb580d10b26a2e3060acc4c5572756e036022f92a /src/cmd/compile/internal/noder
parente1fcf8857e1b3e076cc3a6fad1860afe0d6c2ca6 (diff)
downloadgo-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.go24
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