mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00: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:
parent
975ba6e2b2
commit
6a40dd05d8
1 changed files with 66 additions and 21 deletions
|
|
@ -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 {
|
||||||
info.Types[e] = tv
|
tv.Type = typ
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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 {
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue