mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: panic on uncomparable map key, even if map is empty
Reorg map flags a bit so we don't need any extra space for the extra flag. Fixes #23734 Change-Id: I436812156240ae90de53d0943fe1aabf3ea37417 Reviewed-on: https://go-review.googlesource.com/c/155918 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
14bdcc76fd
commit
ed15e82413
5 changed files with 172 additions and 60 deletions
|
|
@ -1095,6 +1095,28 @@ func needkeyupdate(t *types.Type) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// hashMightPanic reports whether the hash of a map key of type t might panic.
|
||||
func hashMightPanic(t *types.Type) bool {
|
||||
switch t.Etype {
|
||||
case TINTER:
|
||||
return true
|
||||
|
||||
case TARRAY:
|
||||
return hashMightPanic(t.Elem())
|
||||
|
||||
case TSTRUCT:
|
||||
for _, t1 := range t.Fields().Slice() {
|
||||
if hashMightPanic(t1.Type) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// formalType replaces byte and rune aliases with real types.
|
||||
// They've been separate internally to make error messages
|
||||
// better, but we have to merge them in the reflect tables.
|
||||
|
|
@ -1257,25 +1279,33 @@ func dtypesym(t *types.Type) *obj.LSym {
|
|||
ot = dsymptr(lsym, ot, s1, 0)
|
||||
ot = dsymptr(lsym, ot, s2, 0)
|
||||
ot = dsymptr(lsym, ot, s3, 0)
|
||||
var flags uint32
|
||||
// Note: flags must match maptype accessors in ../../../../runtime/type.go
|
||||
// and maptype builder in ../../../../reflect/type.go:MapOf.
|
||||
if t.Key().Width > MAXKEYSIZE {
|
||||
ot = duint8(lsym, ot, uint8(Widthptr))
|
||||
ot = duint8(lsym, ot, 1) // indirect
|
||||
flags |= 1 // indirect key
|
||||
} else {
|
||||
ot = duint8(lsym, ot, uint8(t.Key().Width))
|
||||
ot = duint8(lsym, ot, 0) // not indirect
|
||||
}
|
||||
|
||||
if t.Elem().Width > MAXVALSIZE {
|
||||
ot = duint8(lsym, ot, uint8(Widthptr))
|
||||
ot = duint8(lsym, ot, 1) // indirect
|
||||
flags |= 2 // indirect value
|
||||
} else {
|
||||
ot = duint8(lsym, ot, uint8(t.Elem().Width))
|
||||
ot = duint8(lsym, ot, 0) // not indirect
|
||||
}
|
||||
|
||||
ot = duint16(lsym, ot, uint16(bmap(t).Width))
|
||||
ot = duint8(lsym, ot, uint8(obj.Bool2int(isreflexive(t.Key()))))
|
||||
ot = duint8(lsym, ot, uint8(obj.Bool2int(needkeyupdate(t.Key()))))
|
||||
if isreflexive(t.Key()) {
|
||||
flags |= 4 // reflexive key
|
||||
}
|
||||
if needkeyupdate(t.Key()) {
|
||||
flags |= 8 // need key update
|
||||
}
|
||||
if hashMightPanic(t.Key()) {
|
||||
flags |= 16 // hash might panic
|
||||
}
|
||||
ot = duint32(lsym, ot, flags)
|
||||
ot = dextratype(lsym, ot, t, 0)
|
||||
|
||||
case TPTR:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue