From 46311016894d30b5898382f1f5bada88fb00a34d Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor <ian@gcc.gnu.org> Date: Sat, 4 Feb 2012 01:41:24 +0000 Subject: [PATCH] compiler, reflect: Fix hash codes of named types, fix PtrTo hash. From-SVN: r183889 --- gcc/go/gofrontend/types.cc | 7 ++++++- libgo/go/reflect/all_test.go | 12 ++++++++++++ libgo/go/reflect/type.go | 18 ++++++++++++++++-- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 0bbe3c5b7cab..41bf491dff9e 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -1658,7 +1658,12 @@ Type::type_descriptor_constructor(Gogo* gogo, int runtime_type_kind, ++p; go_assert(p->is_field_name("hash")); - mpz_set_ui(iv, this->hash_for_method(gogo)); + unsigned int h; + if (name != NULL) + h = name->hash_for_method(gogo); + else + h = this->hash_for_method(gogo); + mpz_set_ui(iv, h); vals->push_back(Expression::make_integer(&iv, p->type(), bloc)); ++p; diff --git a/libgo/go/reflect/all_test.go b/libgo/go/reflect/all_test.go index 902a359786db..11dfb3fe516d 100644 --- a/libgo/go/reflect/all_test.go +++ b/libgo/go/reflect/all_test.go @@ -1528,6 +1528,18 @@ func TestAddr(t *testing.T) { if p.X != 4 { t.Errorf("Addr.Elem.Set valued to set value in top value") } + + // Verify that taking the address of a type gives us a pointer + // which we can convert back using the usual interface + // notation. + var s struct { + B *bool + } + ps := ValueOf(&s).Elem().Field(0).Addr().Interface() + *(ps.(**bool)) = new(bool) + if s.B == nil { + t.Errorf("Addr.Interface direct assignment failed") + } } /* gccgo does do allocations here. diff --git a/libgo/go/reflect/type.go b/libgo/go/reflect/type.go index e30cf088bb15..02855df0f390 100644 --- a/libgo/go/reflect/type.go +++ b/libgo/go/reflect/type.go @@ -999,6 +999,17 @@ func (ct *commonType) ptrTo() *commonType { return &p.commonType } + s := "*" + *ct.string + + canonicalTypeLock.RLock() + r, ok := canonicalType[s] + canonicalTypeLock.RUnlock() + if ok { + ptrMap.m[ct] = (*ptrType)(unsafe.Pointer(r.(*commonType))) + ptrMap.Unlock() + return r.(*commonType) + } + rp := new(runtime.PtrType) // initialize p using *byte's ptrType as a prototype. @@ -1008,7 +1019,6 @@ func (ct *commonType) ptrTo() *commonType { bp := (*ptrType)(unsafe.Pointer(unsafe.Typeof((*byte)(nil)).(*runtime.PtrType))) *p = *bp - s := "*" + *ct.string p.string = &s // For the type structures linked into the binary, the @@ -1016,12 +1026,16 @@ func (ct *commonType) ptrTo() *commonType { // Create a good hash for the new string by using // the FNV-1 hash's mixing function to combine the // old hash and the new "*". - p.hash = ct.hash*16777619 ^ '*' + // p.hash = ct.hash*16777619 ^ '*' + // This is the gccgo version. + p.hash = (ct.hash << 4) + 9 p.uncommonType = nil p.ptrToThis = nil p.elem = (*runtime.Type)(unsafe.Pointer(ct)) + p = canonicalize(p).(*ptrType) + ptrMap.m[ct] = p ptrMap.Unlock() return &p.commonType -- GitLab