From: Ian Lance Taylor Date: Thu, 29 Oct 2015 17:14:51 +0000 (+0000) Subject: compiler, runtime: change type hash/equal to Go funcs X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=730f6d14253f7c8f44eff8c03beb5984e2f4c6cf;p=gcc.git compiler, runtime: change type hash/equal to Go funcs Change the type descriptor hash and equal functions from C code pointers to Go func values. This permits them to be set to a Go function closure. This is in preparation for the Go 1.5, so that we can use a closure for the hash/equal functions returned by the new reflect.ArrayOf function. Reviewed-on: https://go-review.googlesource.com/16485 From-SVN: r229541 --- diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 6fcd18593a6..8d3547b3295 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -11e249a59e8c627fe9c2938c38e39cb1efefb1fb +57da43e8159bfe1a31e49683c371cf36e2fb6051 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 0d25dda1f44..c9750bd0aee 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -1197,19 +1197,29 @@ Func_descriptor_expression::do_get_backend(Translate_context* context) Gogo* gogo = context->gogo(); std::string var_name; - if (no->package() == NULL) - var_name = gogo->pkgpath_symbol(); + bool is_descriptor = false; + if (no->is_function_declaration() + && !no->func_declaration_value()->asm_name().empty() + && Linemap::is_predeclared_location(no->location())) + { + var_name = no->func_declaration_value()->asm_name() + "_descriptor"; + is_descriptor = true; + } else - var_name = no->package()->pkgpath_symbol(); - var_name.push_back('.'); - var_name.append(Gogo::unpack_hidden_name(no->name())); - var_name.append("$descriptor"); + { + if (no->package() == NULL) + var_name = gogo->pkgpath_symbol(); + else + var_name = no->package()->pkgpath_symbol(); + var_name.push_back('.'); + var_name.append(Gogo::unpack_hidden_name(no->name())); + var_name.append("$descriptor"); + } Btype* btype = this->type()->get_backend(gogo); Bvariable* bvar; - if (no->package() != NULL - || Linemap::is_predeclared_location(no->location())) + if (no->package() != NULL || is_descriptor) bvar = context->backend()->immutable_struct_reference(var_name, btype, loc); else diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index dcc6bc829c6..5c8950a028b 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -1474,6 +1474,27 @@ Type::make_type_descriptor_type() Type* void_type = Type::make_void_type(); Type* unsafe_pointer_type = Type::make_pointer_type(void_type); + Typed_identifier_list *params = new Typed_identifier_list(); + params->push_back(Typed_identifier("key", unsafe_pointer_type, bloc)); + params->push_back(Typed_identifier("key_size", uintptr_type, bloc)); + + Typed_identifier_list* results = new Typed_identifier_list(); + results->push_back(Typed_identifier("", uintptr_type, bloc)); + + Type* hash_fntype = Type::make_function_type(NULL, params, results, + bloc); + + params = new Typed_identifier_list(); + params->push_back(Typed_identifier("key1", unsafe_pointer_type, bloc)); + params->push_back(Typed_identifier("key2", unsafe_pointer_type, bloc)); + params->push_back(Typed_identifier("key_size", uintptr_type, bloc)); + + results = new Typed_identifier_list(); + results->push_back(Typed_identifier("", Type::lookup_bool_type(), bloc)); + + Type* equal_fntype = Type::make_function_type(NULL, params, results, + bloc); + // Forward declaration for the type descriptor type. Named_object* named_type_descriptor_type = Named_object::make_type_declaration("commonType", NULL, bloc); @@ -1514,8 +1535,8 @@ Type::make_type_descriptor_type() "fieldAlign", uint8_type, "size", uintptr_type, "hash", uint32_type, - "hashfn", uintptr_type, - "equalfn", uintptr_type, + "hashfn", hash_fntype, + "equalfn", equal_fntype, "gc", uintptr_type, "string", pointer_string_type, "", pointer_uncommon_type, @@ -1852,6 +1873,10 @@ Type::write_specific_type_functions(Gogo* gogo, Named_type* name, gogo->add_block(b, bloc); gogo->lower_block(equal_fn, b); gogo->finish_function(bloc); + + // Build the function descriptors for the type descriptor to refer to. + hash_fn->func_value()->descriptor(gogo, hash_fn); + equal_fn->func_value()->descriptor(gogo, equal_fn); } // Write a hash function that simply calls the hash function for a @@ -2009,8 +2034,8 @@ Type::type_descriptor_constructor(Gogo* gogo, int runtime_type_kind, Named_object* equal_fn; this->type_functions(gogo, name, hash_fntype, equal_fntype, &hash_fn, &equal_fn); - vals->push_back(Expression::make_func_code_reference(hash_fn, bloc)); - vals->push_back(Expression::make_func_code_reference(equal_fn, bloc)); + vals->push_back(Expression::make_func_reference(hash_fn, NULL, bloc)); + vals->push_back(Expression::make_func_reference(equal_fn, NULL, bloc)); ++p; go_assert(p->is_field_name("gc")); diff --git a/libgo/go/reflect/type.go b/libgo/go/reflect/type.go index 7f0c6a85a0d..61b195563b6 100644 --- a/libgo/go/reflect/type.go +++ b/libgo/go/reflect/type.go @@ -255,8 +255,8 @@ type rtype struct { size uintptr hash uint32 // hash of type; avoids computation in hash tables - hashfn uintptr // hash function code - equalfn uintptr // equality function code + hashfn func(unsafe.Pointer, uintptr) // hash function + equalfn func(unsafe.Pointer, unsafe.Pointer, uintptr) // equality function gc unsafe.Pointer // garbage collection data string *string // string form; unnecessary but undeniably useful diff --git a/libgo/runtime/go-eface-compare.c b/libgo/runtime/go-eface-compare.c index 3555a65d9cc..40b716eb4af 100644 --- a/libgo/runtime/go-eface-compare.c +++ b/libgo/runtime/go-eface-compare.c @@ -28,8 +28,8 @@ __go_empty_interface_compare (struct __go_empty_interface left, return 1; if (__go_is_pointer_type (left_descriptor)) return left.__object == right.__object ? 0 : 1; - if (!left_descriptor->__equalfn (left.__object, right.__object, - left_descriptor->__size)) + if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object, + right.__object, left_descriptor->__size)) return 1; return 0; } diff --git a/libgo/runtime/go-eface-val-compare.c b/libgo/runtime/go-eface-val-compare.c index 743f126ec1e..e810750d5db 100644 --- a/libgo/runtime/go-eface-val-compare.c +++ b/libgo/runtime/go-eface-val-compare.c @@ -26,8 +26,8 @@ __go_empty_interface_value_compare ( return 1; if (__go_is_pointer_type (left_descriptor)) return left.__object == val ? 0 : 1; - if (!left_descriptor->__equalfn (left.__object, val, - left_descriptor->__size)) + if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object, val, + left_descriptor->__size)) return 1; return 0; } diff --git a/libgo/runtime/go-interface-compare.c b/libgo/runtime/go-interface-compare.c index 6374bd2fb42..1d367753a1e 100644 --- a/libgo/runtime/go-interface-compare.c +++ b/libgo/runtime/go-interface-compare.c @@ -28,8 +28,8 @@ __go_interface_compare (struct __go_interface left, return 1; if (__go_is_pointer_type (left_descriptor)) return left.__object == right.__object ? 0 : 1; - if (!left_descriptor->__equalfn (left.__object, right.__object, - left_descriptor->__size)) + if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object, + right.__object, left_descriptor->__size)) return 1; return 0; } diff --git a/libgo/runtime/go-interface-eface-compare.c b/libgo/runtime/go-interface-eface-compare.c index a38917fd0c6..d1e6fd084d2 100644 --- a/libgo/runtime/go-interface-eface-compare.c +++ b/libgo/runtime/go-interface-eface-compare.c @@ -27,8 +27,8 @@ __go_interface_empty_compare (struct __go_interface left, return 1; if (__go_is_pointer_type (left_descriptor)) return left.__object == right.__object ? 0 : 1; - if (!left_descriptor->__equalfn (left.__object, right.__object, - left_descriptor->__size)) + if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object, + right.__object, left_descriptor->__size)) return 1; return 0; } diff --git a/libgo/runtime/go-interface-val-compare.c b/libgo/runtime/go-interface-val-compare.c index e2dae6a1892..36b6efdc9f1 100644 --- a/libgo/runtime/go-interface-val-compare.c +++ b/libgo/runtime/go-interface-val-compare.c @@ -26,8 +26,8 @@ __go_interface_value_compare ( return 1; if (__go_is_pointer_type (left_descriptor)) return left.__object == val ? 0 : 1; - if (!left_descriptor->__equalfn (left.__object, val, - left_descriptor->__size)) + if (!__go_call_equalfn (left_descriptor->__equalfn, left.__object, val, + left_descriptor->__size)) return 1; return 0; } diff --git a/libgo/runtime/go-map-delete.c b/libgo/runtime/go-map-delete.c index aff25d104bf..fb7c331856e 100644 --- a/libgo/runtime/go-map-delete.c +++ b/libgo/runtime/go-map-delete.c @@ -21,7 +21,7 @@ __go_map_delete (struct __go_map *map, const void *key) const struct __go_map_descriptor *descriptor; const struct __go_type_descriptor *key_descriptor; uintptr_t key_offset; - _Bool (*equalfn) (const void*, const void*, uintptr_t); + const FuncVal *equalfn; size_t key_hash; size_t key_size; size_t bucket_index; @@ -41,14 +41,14 @@ __go_map_delete (struct __go_map *map, const void *key) __go_assert (key_size != -1UL); equalfn = key_descriptor->__equalfn; - key_hash = key_descriptor->__hashfn (key, key_size); + key_hash = __go_call_hashfn (key_descriptor->__hashfn, key, key_size); bucket_index = key_hash % map->__bucket_count; pentry = map->__buckets + bucket_index; while (*pentry != NULL) { char *entry = (char *) *pentry; - if (equalfn (key, entry + key_offset, key_size)) + if (__go_call_equalfn (equalfn, key, entry + key_offset, key_size)) { *pentry = *(void **) entry; if (descriptor->__entry_size >= TinySize) diff --git a/libgo/runtime/go-map-index.c b/libgo/runtime/go-map-index.c index 616b00c68c8..353041db6c4 100644 --- a/libgo/runtime/go-map-index.c +++ b/libgo/runtime/go-map-index.c @@ -22,7 +22,7 @@ __go_map_rehash (struct __go_map *map) const struct __go_type_descriptor *key_descriptor; uintptr_t key_offset; size_t key_size; - uintptr_t (*hashfn) (const void *, uintptr_t); + const FuncVal *hashfn; uintptr_t old_bucket_count; void **old_buckets; uintptr_t new_bucket_count; @@ -55,7 +55,7 @@ __go_map_rehash (struct __go_map *map) /* We could speed up rehashing at the cost of memory space by caching the hash code. */ - key_hash = hashfn (entry + key_offset, key_size); + key_hash = __go_call_hashfn (hashfn, entry + key_offset, key_size); new_bucket_index = key_hash % new_bucket_count; next = *(char **) entry; @@ -82,7 +82,7 @@ __go_map_index (struct __go_map *map, const void *key, _Bool insert) const struct __go_map_descriptor *descriptor; const struct __go_type_descriptor *key_descriptor; uintptr_t key_offset; - _Bool (*equalfn) (const void*, const void*, uintptr_t); + const FuncVal *equalfn; size_t key_hash; size_t key_size; size_t bucket_index; @@ -103,13 +103,13 @@ __go_map_index (struct __go_map *map, const void *key, _Bool insert) __go_assert (key_size != -1UL); equalfn = key_descriptor->__equalfn; - key_hash = key_descriptor->__hashfn (key, key_size); + key_hash = __go_call_hashfn (key_descriptor->__hashfn, key, key_size); bucket_index = key_hash % map->__bucket_count; entry = (char *) map->__buckets[bucket_index]; while (entry != NULL) { - if (equalfn (key, entry + key_offset, key_size)) + if (__go_call_equalfn (equalfn, key, entry + key_offset, key_size)) return entry + descriptor->__val_offset; entry = *(char **) entry; } diff --git a/libgo/runtime/go-reflect-map.c b/libgo/runtime/go-reflect-map.c index 58e1b34a1ea..36f31025d30 100644 --- a/libgo/runtime/go-reflect-map.c +++ b/libgo/runtime/go-reflect-map.c @@ -151,5 +151,6 @@ extern _Bool ismapkey (const struct __go_type_descriptor *) _Bool ismapkey (const struct __go_type_descriptor *typ) { - return typ != NULL && typ->__hashfn != __go_type_hash_error; + return (typ != NULL + && (void *) typ->__hashfn->fn != (void *) __go_type_hash_error); } diff --git a/libgo/runtime/go-type-complex.c b/libgo/runtime/go-type-complex.c index 0f8f0627d73..585984e9fef 100644 --- a/libgo/runtime/go-type-complex.c +++ b/libgo/runtime/go-type-complex.c @@ -84,6 +84,9 @@ __go_type_hash_complex (const void *vkey, uintptr_t key_size) runtime_throw ("__go_type_hash_complex: invalid complex size"); } +const FuncVal __go_type_hash_complex_descriptor = + { (void *) __go_type_hash_complex }; + /* Equality function for complex types. */ _Bool @@ -112,3 +115,6 @@ __go_type_equal_complex (const void *vk1, const void *vk2, uintptr_t key_size) else runtime_throw ("__go_type_equal_complex: invalid complex size"); } + +const FuncVal __go_type_equal_complex_descriptor = + { (void *) __go_type_equal_complex }; diff --git a/libgo/runtime/go-type-eface.c b/libgo/runtime/go-type-eface.c index 30614d25112..315c30efb7f 100644 --- a/libgo/runtime/go-type-eface.c +++ b/libgo/runtime/go-type-eface.c @@ -24,11 +24,14 @@ __go_type_hash_empty_interface (const void *vval, return 0; size = descriptor->__size; if (__go_is_pointer_type (descriptor)) - return descriptor->__hashfn (&val->__object, size); + return __go_call_hashfn (descriptor->__hashfn, &val->__object, size); else - return descriptor->__hashfn (val->__object, size); + return __go_call_hashfn (descriptor->__hashfn, val->__object, size); } +const FuncVal __go_type_hash_empty_interface_descriptor = + { (void *) __go_type_hash_empty_interface }; + /* An equality function for an empty interface. */ _Bool @@ -51,6 +54,9 @@ __go_type_equal_empty_interface (const void *vv1, const void *vv2, if (__go_is_pointer_type (v1_descriptor)) return v1->__object == v2->__object; else - return v1_descriptor->__equalfn (v1->__object, v2->__object, - v1_descriptor->__size); + return __go_call_equalfn (v1_descriptor->__equalfn, v1->__object, + v2->__object, v1_descriptor->__size); } + +const FuncVal __go_type_equal_empty_interface_descriptor = + { (void *) __go_type_equal_empty_interface }; diff --git a/libgo/runtime/go-type-error.c b/libgo/runtime/go-type-error.c index b4c609b93ec..8881a86f6e0 100644 --- a/libgo/runtime/go-type-error.c +++ b/libgo/runtime/go-type-error.c @@ -17,6 +17,9 @@ __go_type_hash_error (const void *val __attribute__ ((unused)), runtime_panicstring ("hash of unhashable type"); } +const FuncVal __go_type_hash_error_descriptor = + { (void *) __go_type_hash_error }; + /* An equality function for an interface. */ _Bool @@ -26,3 +29,6 @@ __go_type_equal_error (const void *v1 __attribute__ ((unused)), { runtime_panicstring ("comparing uncomparable types"); } + +const FuncVal __go_type_equal_error_descriptor = + { (void *) __go_type_equal_error }; diff --git a/libgo/runtime/go-type-float.c b/libgo/runtime/go-type-float.c index 4ae73470de9..39f9b29ae7d 100644 --- a/libgo/runtime/go-type-float.c +++ b/libgo/runtime/go-type-float.c @@ -56,6 +56,9 @@ __go_type_hash_float (const void *vkey, uintptr_t key_size) runtime_throw ("__go_type_hash_float: invalid float size"); } +const FuncVal __go_type_hash_float_descriptor = + { (void *) __go_type_hash_float }; + /* Equality function for float types. */ _Bool @@ -84,3 +87,6 @@ __go_type_equal_float (const void *vk1, const void *vk2, uintptr_t key_size) else runtime_throw ("__go_type_equal_float: invalid float size"); } + +const FuncVal __go_type_equal_float_descriptor = + { (void *) __go_type_equal_float }; diff --git a/libgo/runtime/go-type-identity.c b/libgo/runtime/go-type-identity.c index ed510f75a72..a334d56cbe4 100644 --- a/libgo/runtime/go-type-identity.c +++ b/libgo/runtime/go-type-identity.c @@ -45,6 +45,9 @@ __go_type_hash_identity (const void *key, uintptr_t key_size) return ret; } +const FuncVal __go_type_hash_identity_descriptor = + { (void *) __go_type_hash_identity }; + /* An identity equality function for a type. This is used for types where we can check for equality by checking that the values have the same bits. */ @@ -54,3 +57,6 @@ __go_type_equal_identity (const void *k1, const void *k2, uintptr_t key_size) { return __builtin_memcmp (k1, k2, key_size) == 0; } + +const FuncVal __go_type_equal_identity_descriptor = + { (void *) __go_type_equal_identity }; diff --git a/libgo/runtime/go-type-interface.c b/libgo/runtime/go-type-interface.c index 9aad720085c..e9e577956eb 100644 --- a/libgo/runtime/go-type-interface.c +++ b/libgo/runtime/go-type-interface.c @@ -24,11 +24,14 @@ __go_type_hash_interface (const void *vval, descriptor = (const struct __go_type_descriptor *) val->__methods[0]; size = descriptor->__size; if (__go_is_pointer_type (descriptor)) - return descriptor->__hashfn (&val->__object, size); + return __go_call_hashfn (descriptor->__hashfn, &val->__object, size); else - return descriptor->__hashfn (val->__object, size); + return __go_call_hashfn (descriptor->__hashfn, val->__object, size); } +const FuncVal __go_type_hash_interface_descriptor = + { (void *) __go_type_hash_interface }; + /* An equality function for an interface. */ _Bool @@ -51,6 +54,9 @@ __go_type_equal_interface (const void *vv1, const void *vv2, if (__go_is_pointer_type (v1_descriptor)) return v1->__object == v2->__object; else - return v1_descriptor->__equalfn (v1->__object, v2->__object, - v1_descriptor->__size); + return __go_call_equalfn (v1_descriptor->__equalfn, v1->__object, + v2->__object, v1_descriptor->__size); } + +const FuncVal __go_type_equal_interface_descriptor = + { (void *) __go_type_equal_interface }; diff --git a/libgo/runtime/go-type-string.c b/libgo/runtime/go-type-string.c index a96af0290b2..3d33d6ee510 100644 --- a/libgo/runtime/go-type-string.c +++ b/libgo/runtime/go-type-string.c @@ -28,6 +28,9 @@ __go_type_hash_string (const void *vkey, return ret; } +const FuncVal __go_type_hash_string_descriptor = + { (void *) __go_type_hash_string }; + /* A string equality function for a map. */ _Bool @@ -41,3 +44,6 @@ __go_type_equal_string (const void *vk1, const void *vk2, k2 = (const String *) vk2; return __go_ptr_strings_equal (k1, k2); } + +const FuncVal __go_type_equal_string_descriptor = + { (void *) __go_type_equal_string }; diff --git a/libgo/runtime/go-type.h b/libgo/runtime/go-type.h index d7693353039..72c9f56986e 100644 --- a/libgo/runtime/go-type.h +++ b/libgo/runtime/go-type.h @@ -89,11 +89,11 @@ struct __go_type_descriptor size of this type, and returns a hash code. We pass the size explicitly becaues it means that we can share a single instance of this function for various different types. */ - uintptr_t (*__hashfn) (const void *, uintptr_t); + const FuncVal *__hashfn; /* This function takes two pointers to values of this type, and the size of this type, and returns whether the values are equal. */ - _Bool (*__equalfn) (const void *, const void *, uintptr_t); + const FuncVal *__equalfn; /* The garbage collection data. */ const uintptr *__gc; @@ -316,21 +316,52 @@ __go_is_pointer_type (const struct __go_type_descriptor *td) || (td->__code & GO_CODE_MASK) == GO_UNSAFE_POINTER); } +/* Call a type hash function, given the __hashfn value. */ + +static inline uintptr_t +__go_call_hashfn (const FuncVal *hashfn, const void *p, uintptr_t size) +{ + uintptr_t (*h) (const void *, uintptr_t) = (void *) hashfn->fn; + return __builtin_call_with_static_chain (h (p, size), hashfn); +} + +/* Call a type equality function, given the __equalfn value. */ + +static inline _Bool +__go_call_equalfn (const FuncVal *equalfn, const void *p1, const void *p2, + uintptr_t size) +{ + _Bool (*e) (const void *, const void *, uintptr_t) = (void *) equalfn->fn; + return __builtin_call_with_static_chain (e (p1, p2, size), equalfn); +} + extern _Bool __go_type_descriptors_equal(const struct __go_type_descriptor*, const struct __go_type_descriptor*); extern uintptr_t __go_type_hash_identity (const void *, uintptr_t); +extern const FuncVal __go_type_hash_identity_descriptor; extern _Bool __go_type_equal_identity (const void *, const void *, uintptr_t); +extern const FuncVal __go_type_equal_identity_descriptor; extern uintptr_t __go_type_hash_string (const void *, uintptr_t); +extern const FuncVal __go_type_hash_string_descriptor; extern _Bool __go_type_equal_string (const void *, const void *, uintptr_t); +extern const FuncVal __go_type_equal_string_descriptor; extern uintptr_t __go_type_hash_float (const void *, uintptr_t); +extern const FuncVal __go_type_hash_float_descriptor; extern _Bool __go_type_equal_float (const void *, const void *, uintptr_t); +extern const FuncVal __go_type_equal_float_descriptor; extern uintptr_t __go_type_hash_complex (const void *, uintptr_t); +extern const FuncVal __go_type_hash_complex_descriptor; extern _Bool __go_type_equal_complex (const void *, const void *, uintptr_t); +extern const FuncVal __go_type_equal_complex_descriptor; extern uintptr_t __go_type_hash_interface (const void *, uintptr_t); +extern const FuncVal __go_type_hash_interface_descriptor; extern _Bool __go_type_equal_interface (const void *, const void *, uintptr_t); +extern const FuncVal __go_type_equal_interface_descriptor; extern uintptr_t __go_type_hash_error (const void *, uintptr_t); +extern const FuncVal __go_type_hash_error_descriptor; extern _Bool __go_type_equal_error (const void *, const void *, uintptr_t); +extern const FuncVal __go_type_equal_error_descriptor; #endif /* !defined(LIBGO_GO_TYPE_H) */ diff --git a/libgo/runtime/go-unsafe-pointer.c b/libgo/runtime/go-unsafe-pointer.c index 71364f511b4..a59ae852185 100644 --- a/libgo/runtime/go-unsafe-pointer.c +++ b/libgo/runtime/go-unsafe-pointer.c @@ -54,9 +54,9 @@ const struct __go_type_descriptor unsafe_Pointer = /* __hash */ 78501163U, /* __hashfn */ - __go_type_hash_identity, + &__go_type_hash_identity_descriptor, /* __equalfn */ - __go_type_equal_identity, + &__go_type_equal_identity_descriptor, /* __gc */ unsafe_Pointer_gc, /* __reflection */ @@ -99,9 +99,9 @@ const struct __go_ptr_type pointer_unsafe_Pointer = /* __hash */ 1256018616U, /* __hashfn */ - __go_type_hash_identity, + &__go_type_hash_identity_descriptor, /* __equalfn */ - __go_type_equal_identity, + &__go_type_equal_identity_descriptor, /* __gc */ unsafe_Pointer_gc, /* __reflection */ diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c index babad01ea95..db8b94f28f7 100644 --- a/libgo/runtime/proc.c +++ b/libgo/runtime/proc.c @@ -528,9 +528,9 @@ static struct __go_channel_type chan_bool_type_descriptor = /* __hash */ 0, /* This value doesn't matter. */ /* __hashfn */ - __go_type_hash_error, + &__go_type_hash_error_descriptor, /* __equalfn */ - __go_type_equal_error, + &__go_type_equal_error_descriptor, /* __gc */ NULL, /* This value doesn't matter */ /* __reflection */