1
0
mirror of https://github.com/golang/go synced 2024-10-01 10:28:31 -06:00

cmd/compile: stop generating garbage when checking map key types

Change-Id: Ib500ee92ae1a3d15f7c9f3f46d238b75184b4304
Reviewed-on: https://go-review.googlesource.com/21382
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Matthew Dempsky 2016-03-31 12:30:20 -07:00
parent 00289c296c
commit 7c4d53c2c8
4 changed files with 33 additions and 32 deletions

View File

@ -3018,7 +3018,7 @@ func (p *parser) hidden_type_misc() *Type {
p.want(']') p.want(']')
s5 := p.hidden_type() s5 := p.hidden_type()
return maptype(s3, s5) return typMap(s3, s5)
case LSTRUCT: case LSTRUCT:
// LSTRUCT '{' ohidden_structdcl_list '}' // LSTRUCT '{' ohidden_structdcl_list '}'

View File

@ -372,40 +372,37 @@ func saveorignode(n *Node) {
n.Orig = norig n.Orig = norig
} }
func maptype(key *Type, val *Type) *Type { // checkMapKeyType checks that Type key is valid for use as a map key.
if key != nil { func checkMapKeyType(key *Type) {
var bad *Type var bad *Type
atype := algtype1(key, &bad) atype := algtype1(key, &bad)
var mtype EType var mtype EType
if bad == nil { if bad == nil {
mtype = key.Etype mtype = key.Etype
} else { } else {
mtype = bad.Etype mtype = bad.Etype
}
switch mtype {
default:
if atype == ANOEQ {
Yyerror("invalid map key type %v", key)
} }
switch mtype {
default:
if atype == ANOEQ {
Yyerror("invalid map key type %v", key)
}
case TANY: case TANY:
// will be resolved later. // will be resolved later.
break break
case TFORW: case TFORW:
// map[key] used during definition of key. // map[key] used during definition of key.
// postpone check until key is fully defined. // postpone check until key is fully defined.
// if there are multiple uses of map[key] // if there are multiple uses of map[key]
// before key is fully defined, the error // before key is fully defined, the error
// will only be printed for the first one. // will only be printed for the first one.
// good enough. // good enough.
if key.Maplineno == 0 { if key.Maplineno == 0 {
key.Maplineno = lineno key.Maplineno = lineno
}
} }
} }
return typMap(key, val)
} }
// methcmp sorts by symbol, then by package path for unexported symbols. // methcmp sorts by symbol, then by package path for unexported symbols.

View File

@ -275,6 +275,10 @@ func typChan(elem *Type, dir uint8) *Type {
// typMap returns a new map Type with key type k and element (aka value) type v. // typMap returns a new map Type with key type k and element (aka value) type v.
func typMap(k, v *Type) *Type { func typMap(k, v *Type) *Type {
if k != nil {
checkMapKeyType(k)
}
t := typ(TMAP) t := typ(TMAP)
t.Down = k t.Down = k
t.Type = v t.Type = v

View File

@ -402,7 +402,7 @@ OpSwitch:
return n return n
} }
n.Op = OTYPE n.Op = OTYPE
n.Type = maptype(l.Type, r.Type) n.Type = typMap(l.Type, r.Type)
n.Left = nil n.Left = nil
n.Right = nil n.Right = nil
@ -3595,7 +3595,7 @@ ret:
for _, n := range mapqueue { for _, n := range mapqueue {
lineno = n.Type.Maplineno lineno = n.Type.Maplineno
maptype(n.Type, Types[TBOOL]) checkMapKeyType(n.Type)
} }
lineno = lno lineno = lno