summaryrefslogtreecommitdiff
path: root/libgo
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2012-02-04 01:41:24 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2012-02-04 01:41:24 +0000
commit7134be81f2a6d1d5775a659fb4f7de743bf516a0 (patch)
tree5f1c68fe8bf58b8564c9fcffd911fd3b50a73d9c /libgo
parentd9936931d7e5c60514c401d0351e65a6d9404885 (diff)
downloadgcc-7134be81f2a6d1d5775a659fb4f7de743bf516a0.tar.gz
compiler, reflect: Fix hash codes of named types, fix PtrTo hash.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@183889 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo')
-rw-r--r--libgo/go/reflect/all_test.go12
-rw-r--r--libgo/go/reflect/type.go18
2 files changed, 28 insertions, 2 deletions
diff --git a/libgo/go/reflect/all_test.go b/libgo/go/reflect/all_test.go
index 902a359786d..11dfb3fe516 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 e30cf088bb1..02855df0f39 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