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. // Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package types2 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) { func sanitizeInfo(info *Info) {
var s sanitizer = make(map[Type]Type) var s sanitizer = make(map[Type]Type)
@ -12,27 +18,42 @@ func sanitizeInfo(info *Info) {
// If modified, they must be assigned back. // If modified, they must be assigned back.
for e, tv := range info.Types { for e, tv := range info.Types {
tv.Type = s.typ(tv.Type) if typ := s.typ(tv.Type); typ != tv.Type {
tv.Type = typ
info.Types[e] = tv info.Types[e] = tv
} }
}
for e, inf := range info.Inferred { for e, inf := range info.Inferred {
changed := false
for i, targ := range inf.Targs { 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
} }
inf.Sig = s.typ(inf.Sig).(*Signature) }
if typ := s.typ(inf.Sig); typ != inf.Sig {
inf.Sig = typ.(*Signature)
changed = true
}
if changed {
info.Inferred[e] = inf info.Inferred[e] = inf
} }
}
for _, obj := range info.Defs { for _, obj := range info.Defs {
if obj != nil { 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 { for _, obj := range info.Uses {
if obj != nil { 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 // nothing to do
case *Array: case *Array:
t.elem = s.typ(t.elem) if elem := s.typ(t.elem); elem != t.elem {
t.elem = elem
}
case *Slice: case *Slice:
t.elem = s.typ(t.elem) if elem := s.typ(t.elem); elem != t.elem {
t.elem = elem
}
case *Struct: case *Struct:
s.varList(t.fields) s.varList(t.fields)
case *Pointer: case *Pointer:
t.base = s.typ(t.base) if base := s.typ(t.base); base != t.base {
t.base = base
}
case *Tuple: case *Tuple:
s.tuple(t) s.tuple(t)
@ -86,27 +113,39 @@ func (s sanitizer) typ(typ Type) Type {
s.typ(t.allTypes) s.typ(t.allTypes)
case *Map: case *Map:
t.key = s.typ(t.key) if key := s.typ(t.key); key != t.key {
t.elem = s.typ(t.elem) t.key = key
}
if elem := s.typ(t.elem); elem != t.elem {
t.elem = elem
}
case *Chan: case *Chan:
t.elem = s.typ(t.elem) if elem := s.typ(t.elem); elem != t.elem {
t.elem = elem
}
case *Named: case *Named:
t.orig = s.typ(t.orig) if orig := s.typ(t.orig); orig != t.orig {
t.underlying = s.typ(t.underlying) t.orig = orig
}
if under := s.typ(t.underlying); under != t.underlying {
t.underlying = under
}
s.typeList(t.targs) s.typeList(t.targs)
s.funcList(t.methods) s.funcList(t.methods)
case *TypeParam: case *TypeParam:
t.bound = s.typ(t.bound) if bound := s.typ(t.bound); bound != t.bound {
t.bound = bound
}
case *instance: case *instance:
typ = t.expand() typ = t.expand()
s[t] = typ s[t] = typ
default: default:
unimplemented() panic("unimplemented")
} }
return typ return typ
@ -114,7 +153,9 @@ func (s sanitizer) typ(typ Type) Type {
func (s sanitizer) var_(v *Var) { func (s sanitizer) var_(v *Var) {
if v != nil { 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) { func (s sanitizer) func_(f *Func) {
if f != nil { 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) { func (s sanitizer) typeList(list []Type) {
for i, t := range list { for i, t := range list {
list[i] = s.typ(t) if typ := s.typ(t); typ != t {
list[i] = typ
}
} }
} }