Commit 88cf76a9 authored by Rob Pike's avatar Rob Pike

gob: fix bug when registering the same type multiple times

Need to compare user type, not base type.

R=golang-dev, dsymonds, r
CC=golang-dev
https://golang.org/cl/5340041
parent a494c200
...@@ -703,18 +703,19 @@ func RegisterName(name string, value interface{}) { ...@@ -703,18 +703,19 @@ func RegisterName(name string, value interface{}) {
// reserved for nil // reserved for nil
panic("attempt to register empty name") panic("attempt to register empty name")
} }
base := userType(reflect.TypeOf(value)).base ut := userType(reflect.TypeOf(value))
// Check for incompatible duplicates. // Check for incompatible duplicates. The name must refer to the
if t, ok := nameToConcreteType[name]; ok && t != base { // same user type, and vice versa.
panic("gob: registering duplicate types for " + name) if t, ok := nameToConcreteType[name]; ok && t != ut.user {
panic(fmt.Sprintf("gob: registering duplicate types for %q: %s != %s", name, t, ut.user))
} }
if n, ok := concreteTypeToName[base]; ok && n != name { if n, ok := concreteTypeToName[ut.base]; ok && n != name {
panic("gob: registering duplicate names for " + base.String()) panic(fmt.Sprintf("gob: registering duplicate names for %s: %q != %q", ut.user, n, name))
} }
// Store the name and type provided by the user.... // Store the name and type provided by the user....
nameToConcreteType[name] = reflect.TypeOf(value) nameToConcreteType[name] = reflect.TypeOf(value)
// but the flattened type in the type table, since that's what decode needs. // but the flattened type in the type table, since that's what decode needs.
concreteTypeToName[base] = name concreteTypeToName[ut.base] = name
} }
// Register records a type, identified by a value for that type, under its // Register records a type, identified by a value for that type, under its
......
...@@ -151,3 +151,11 @@ func TestStructType(t *testing.T) { ...@@ -151,3 +151,11 @@ func TestStructType(t *testing.T) {
t.Errorf("struct printed as %q; expected %q", str, expected) t.Errorf("struct printed as %q; expected %q", str, expected)
} }
} }
// Should be OK to register the same type multiple times, as long as they're
// at the same level of indirection.
func TestRegistration(t *testing.T) {
type T struct{ a int }
Register(new(T))
Register(new(T))
}
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