]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
compiler, reflect: Fix hash codes of named types, fix PtrTo hash.
authorIan Lance Taylor <ian@gcc.gnu.org>
Sat, 4 Feb 2012 01:41:24 +0000 (01:41 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Sat, 4 Feb 2012 01:41:24 +0000 (01:41 +0000)
From-SVN: r183889

gcc/go/gofrontend/types.cc
libgo/go/reflect/all_test.go
libgo/go/reflect/type.go

index 0bbe3c5b7cabcbdcac127cb34144628b8f37b08e..41bf491dff9e7474d42341f5b80d36b78c393620 100644 (file)
@@ -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;
index 902a359786dbe2d7e8f76e80e722c24a8e94bd73..11dfb3fe516d89fc90b7e96276f01186705a0b2b 100644 (file)
@@ -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.
index e30cf088bb153fdbefc66c0cfeca28765160e7ba..02855df0f390905226e88f52b28591c5ca9bdadf 100644 (file)
@@ -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