1
0
mirror of https://github.com/golang/go synced 2024-11-19 03:04:42 -07:00

cmd/compile/internal/types2: review of sanitize.go

Remove the "// UNREVIEWED" marker and add guards (as in go/types)
to prevent data races. To see the added guards, see compare patch
sets 3 and 4. The equivalent changes for go/types were done in
https://golang.org/cl/294411.

Change-Id: Ibef07eaae400bd32bff32b102cc743580290d135
Reviewed-on: https://go-review.googlesource.com/c/go/+/294510
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Robert Griesemer 2021-02-19 20:06:24 -08:00
parent 975ba6e2b2
commit 6a40dd05d8

View File

@ -1,10 +1,16 @@
// UNREVIEWED
// Copyright 2020 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 types2
// sanitizeInfo walks the types contained in info to ensure that all instances
// are expanded.
//
// This includes some objects that may be shared across concurrent
// type-checking passes (such as those in the universe scope), so we are
// careful here not to write types that are already sanitized. This avoids a
// data race as any shared types should already be sanitized.
func sanitizeInfo(info *Info) {
var s sanitizer = make(map[Type]Type)
@ -12,27 +18,42 @@ func sanitizeInfo(info *Info) {
// If modified, they must be assigned back.
for e, tv := range info.Types {
tv.Type = s.typ(tv.Type)
info.Types[e] = tv
if typ := s.typ(tv.Type); typ != tv.Type {
tv.Type = typ
info.Types[e] = tv
}
}
for e, inf := range info.Inferred {
changed := false
for i, targ := range inf.Targs {
inf.Targs[i] = s.typ(targ)
if typ := s.typ(targ); typ != targ {
inf.Targs[i] = typ
changed = true
}
}
if typ := s.typ(inf.Sig); typ != inf.Sig {
inf.Sig = typ.(*Signature)
changed = true
}
if changed {
info.Inferred[e] = inf
}
inf.Sig = s.typ(inf.Sig).(*Signature)
info.Inferred[e] = inf
}
for _, obj := range info.Defs {
if obj != nil {
obj.setType(s.typ(obj.Type()))
if typ := s.typ(obj.Type()); typ != obj.Type() {
obj.setType(typ)
}
}
}
for _, obj := range info.Uses {
if obj != nil {
obj.setType(s.typ(obj.Type()))
if typ := s.typ(obj.Type()); typ != obj.Type() {
obj.setType(typ)
}
}
}
@ -56,16 +77,22 @@ func (s sanitizer) typ(typ Type) Type {
// nothing to do
case *Array:
t.elem = s.typ(t.elem)
if elem := s.typ(t.elem); elem != t.elem {
t.elem = elem
}
case *Slice:
t.elem = s.typ(t.elem)
if elem := s.typ(t.elem); elem != t.elem {
t.elem = elem
}
case *Struct:
s.varList(t.fields)
case *Pointer:
t.base = s.typ(t.base)
if base := s.typ(t.base); base != t.base {
t.base = base
}
case *Tuple:
s.tuple(t)
@ -86,27 +113,39 @@ func (s sanitizer) typ(typ Type) Type {
s.typ(t.allTypes)
case *Map:
t.key = s.typ(t.key)
t.elem = s.typ(t.elem)
if key := s.typ(t.key); key != t.key {
t.key = key
}
if elem := s.typ(t.elem); elem != t.elem {
t.elem = elem
}
case *Chan:
t.elem = s.typ(t.elem)
if elem := s.typ(t.elem); elem != t.elem {
t.elem = elem
}
case *Named:
t.orig = s.typ(t.orig)
t.underlying = s.typ(t.underlying)
if orig := s.typ(t.orig); orig != t.orig {
t.orig = orig
}
if under := s.typ(t.underlying); under != t.underlying {
t.underlying = under
}
s.typeList(t.targs)
s.funcList(t.methods)
case *TypeParam:
t.bound = s.typ(t.bound)
if bound := s.typ(t.bound); bound != t.bound {
t.bound = bound
}
case *instance:
typ = t.expand()
s[t] = typ
default:
unimplemented()
panic("unimplemented")
}
return typ
@ -114,7 +153,9 @@ func (s sanitizer) typ(typ Type) Type {
func (s sanitizer) var_(v *Var) {
if v != nil {
v.typ = s.typ(v.typ)
if typ := s.typ(v.typ); typ != v.typ {
v.typ = typ
}
}
}
@ -132,7 +173,9 @@ func (s sanitizer) tuple(t *Tuple) {
func (s sanitizer) func_(f *Func) {
if f != nil {
f.typ = s.typ(f.typ)
if typ := s.typ(f.typ); typ != f.typ {
f.typ = typ
}
}
}
@ -144,6 +187,8 @@ func (s sanitizer) funcList(list []*Func) {
func (s sanitizer) typeList(list []Type) {
for i, t := range list {
list[i] = s.typ(t)
if typ := s.typ(t); typ != t {
list[i] = typ
}
}
}