Commit 7c4d53c2 authored by Matthew Dempsky's avatar Matthew Dempsky

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

Change-Id: Ib500ee92ae1a3d15f7c9f3f46d238b75184b4304
Reviewed-on: https://go-review.googlesource.com/21382Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 00289c29
......@@ -3018,7 +3018,7 @@ func (p *parser) hidden_type_misc() *Type {
p.want(']')
s5 := p.hidden_type()
return maptype(s3, s5)
return typMap(s3, s5)
case LSTRUCT:
// LSTRUCT '{' ohidden_structdcl_list '}'
......
......@@ -372,40 +372,37 @@ func saveorignode(n *Node) {
n.Orig = norig
}
func maptype(key *Type, val *Type) *Type {
if key != nil {
var bad *Type
atype := algtype1(key, &bad)
var mtype EType
if bad == nil {
mtype = key.Etype
} else {
mtype = bad.Etype
// checkMapKeyType checks that Type key is valid for use as a map key.
func checkMapKeyType(key *Type) {
var bad *Type
atype := algtype1(key, &bad)
var mtype EType
if bad == nil {
mtype = key.Etype
} else {
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:
// will be resolved later.
break
case TANY:
// will be resolved later.
break
case TFORW:
// map[key] used during definition of key.
// postpone check until key is fully defined.
// if there are multiple uses of map[key]
// before key is fully defined, the error
// will only be printed for the first one.
// good enough.
if key.Maplineno == 0 {
key.Maplineno = lineno
}
case TFORW:
// map[key] used during definition of key.
// postpone check until key is fully defined.
// if there are multiple uses of map[key]
// before key is fully defined, the error
// will only be printed for the first one.
// good enough.
if key.Maplineno == 0 {
key.Maplineno = lineno
}
}
return typMap(key, val)
}
// methcmp sorts by symbol, then by package path for unexported symbols.
......
......@@ -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.
func typMap(k, v *Type) *Type {
if k != nil {
checkMapKeyType(k)
}
t := typ(TMAP)
t.Down = k
t.Type = v
......
......@@ -402,7 +402,7 @@ OpSwitch:
return n
}
n.Op = OTYPE
n.Type = maptype(l.Type, r.Type)
n.Type = typMap(l.Type, r.Type)
n.Left = nil
n.Right = nil
......@@ -3595,7 +3595,7 @@ ret:
for _, n := range mapqueue {
lineno = n.Type.Maplineno
maptype(n.Type, Types[TBOOL])
checkMapKeyType(n.Type)
}
lineno = lno
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment