Skip to content

Commit

Permalink
cmd/compile/internal/types2: review of sanitize.go
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
griesemer committed Feb 23, 2021
1 parent 975ba6e commit 6a40dd0
Showing 1 changed file with 66 additions and 21 deletions.
87 changes: 66 additions & 21 deletions src/cmd/compile/internal/types2/sanitize.go
Original file line number Diff line number Diff line change
@@ -1,38 +1,59 @@
// 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)

// Note: Some map entries are not references.
// 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)
}
}
}

Expand All @@ -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)
Expand All @@ -86,35 +113,49 @@ 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
}

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
}
}
}

Expand All @@ -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
}
}
}

Expand All @@ -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
}
}
}

0 comments on commit 6a40dd0

Please sign in to comment.