diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-02-15 01:57:51 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-02-15 01:57:51 +0000 |
commit | 8a9f2a6bbd6bdf164ca987edac34ac72447881a5 (patch) | |
tree | 0722c462bd08d8478a0d1861b10b9f966193505e /gcc | |
parent | c8530c410972f09b88bb143e5e5a4910bd72b2ee (diff) | |
download | gcc-8a9f2a6bbd6bdf164ca987edac34ac72447881a5.zip gcc-8a9f2a6bbd6bdf164ca987edac34ac72447881a5.tar.gz gcc-8a9f2a6bbd6bdf164ca987edac34ac72447881a5.tar.bz2 |
compiler, runtime: harmonize types referenced by both C and Go
Compiling with LTO revealed a number of cases in the runtime and
standard library where C and Go disagreed about the type of an object or
function (or where Go and code generated by the compiler disagreed). In
all cases the underlying representation was the same (e.g., uintptr vs.
void*), so this wasn't causing actual problems, but it did result in a
number of annoying warnings when compiling with LTO.
Reviewed-on: https://go-review.googlesource.com/c/160700
From-SVN: r268923
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 6 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.cc | 5 | ||||
-rw-r--r-- | gcc/go/gofrontend/runtime.cc | 12 | ||||
-rw-r--r-- | gcc/go/gofrontend/runtime.def | 10 | ||||
-rw-r--r-- | gcc/go/gofrontend/wb.cc | 36 |
6 files changed, 42 insertions, 29 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index e8d4f99..4b603d9 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -4a6f2bb2c8d3f00966f001a5b03c57cb4a278265 +03e28273a4fcb114f5204d52ed107591404002f4 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 40b9f18..d46c754 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -1344,7 +1344,7 @@ Func_descriptor_expression::make_func_descriptor_type() if (Func_descriptor_expression::descriptor_type != NULL) return; Type* uintptr_type = Type::lookup_integer_type("uintptr"); - Type* struct_type = Type::make_builtin_struct_type(1, "code", uintptr_type); + Type* struct_type = Type::make_builtin_struct_type(1, "fn", uintptr_type); Func_descriptor_expression::descriptor_type = Type::make_builtin_named_type("functionDescriptor", struct_type); } @@ -3874,7 +3874,9 @@ Unsafe_type_conversion_expression::do_get_backend(Translate_context* context) || et->integer_type() != NULL || et->is_nil_type()); else if (et->is_unsafe_pointer_type()) - go_assert(t->points_to() != NULL); + go_assert(t->points_to() != NULL + || (t->integer_type() != NULL + && t->integer_type() == Type::lookup_integer_type("uintptr")->real_type())); else if (t->interface_type() != NULL) { bool empty_iface = t->interface_type()->is_empty(); diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 79c3cc9..9bd25fa 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -4513,13 +4513,13 @@ Build_recover_thunks::can_recover_arg(Location location) builtin_return_address = Gogo::declare_builtin_rf_address("__builtin_return_address"); + Type* uintptr_type = Type::lookup_integer_type("uintptr"); static Named_object* can_recover; if (can_recover == NULL) { const Location bloc = Linemap::predeclared_location(); Typed_identifier_list* param_types = new Typed_identifier_list(); - Type* voidptr_type = Type::make_pointer_type(Type::make_void_type()); - param_types->push_back(Typed_identifier("a", voidptr_type, bloc)); + param_types->push_back(Typed_identifier("a", uintptr_type, bloc)); Type* boolean_type = Type::lookup_bool_type(); Typed_identifier_list* results = new Typed_identifier_list(); results->push_back(Typed_identifier("", boolean_type, bloc)); @@ -4539,6 +4539,7 @@ Build_recover_thunks::can_recover_arg(Location location) args->push_back(zexpr); Expression* call = Expression::make_call(fn, args, false, location); + call = Expression::make_unsafe_cast(uintptr_type, call, location); args = new Expression_list(); args->push_back(call); diff --git a/gcc/go/gofrontend/runtime.cc b/gcc/go/gofrontend/runtime.cc index bb30cc1..7ecbf68 100644 --- a/gcc/go/gofrontend/runtime.cc +++ b/gcc/go/gofrontend/runtime.cc @@ -60,8 +60,6 @@ enum Runtime_function_type RFT_IFACE, // Go type interface{}, C type struct __go_empty_interface. RFT_EFACE, - // Go type func(unsafe.Pointer), C type void (*) (void *). - RFT_FUNC_PTR, // Pointer to Go type descriptor. RFT_TYPE, // [2]string. @@ -176,15 +174,6 @@ runtime_function_type(Runtime_function_type bft) t = Type::make_empty_interface_type(bloc); break; - case RFT_FUNC_PTR: - { - Typed_identifier_list* param_types = new Typed_identifier_list(); - Type* ptrtype = runtime_function_type(RFT_POINTER); - param_types->push_back(Typed_identifier("", ptrtype, bloc)); - t = Type::make_function_type(NULL, param_types, NULL, bloc); - } - break; - case RFT_TYPE: t = Type::make_type_descriptor_ptr_type(); break; @@ -265,7 +254,6 @@ convert_to_runtime_function_type(Runtime_function_type bft, Expression* e, case RFT_COMPLEX128: case RFT_STRING: case RFT_POINTER: - case RFT_FUNC_PTR: { Type* t = runtime_function_type(bft); if (!Type::are_identical(t, e->type(), true, NULL)) diff --git a/gcc/go/gofrontend/runtime.def b/gcc/go/gofrontend/runtime.def index ded6251..273c860 100644 --- a/gcc/go/gofrontend/runtime.def +++ b/gcc/go/gofrontend/runtime.def @@ -168,10 +168,10 @@ DEF_GO_RUNTIME(GORECOVER, "runtime.gorecover", P0(), R1(EFACE)) DEF_GO_RUNTIME(DEFERREDRECOVER, "runtime.deferredrecover", P0(), R1(EFACE)) // Decide whether this function can call recover. -DEF_GO_RUNTIME(CANRECOVER, "runtime.canrecover", P1(POINTER), R1(BOOL)) +DEF_GO_RUNTIME(CANRECOVER, "runtime.canrecover", P1(UINTPTR), R1(BOOL)) // Set the return address for defer in a defer thunk. -DEF_GO_RUNTIME(SETDEFERRETADDR, "runtime.setdeferretaddr", P1(POINTER), +DEF_GO_RUNTIME(SETDEFERRETADDR, "runtime.setdeferretaddr", P1(UINTPTR), R1(BOOL)) // Check for a deferred function in an exception handler. @@ -213,10 +213,10 @@ DEF_GO_RUNTIME(REGISTER_GC_ROOTS, "runtime.registerGCRoots", P1(POINTER), R0()) DEF_GO_RUNTIME(NEW, "runtime.newobject", P1(TYPE), R1(POINTER)) // Start a new goroutine. -DEF_GO_RUNTIME(GO, "__go_go", P2(FUNC_PTR, POINTER), R0()) +DEF_GO_RUNTIME(GO, "__go_go", P2(UINTPTR, POINTER), R1(POINTER)) // Defer a function. -DEF_GO_RUNTIME(DEFERPROC, "runtime.deferproc", P3(BOOLPTR, FUNC_PTR, POINTER), +DEF_GO_RUNTIME(DEFERPROC, "runtime.deferproc", P3(BOOLPTR, UINTPTR, POINTER), R0()) @@ -303,7 +303,7 @@ DEF_GO_RUNTIME(IFACEEFACEEQ, "runtime.ifaceefaceeq", P2(IFACE, EFACE), // Set *dst = src where dst is a pointer to a pointer and src is a pointer. DEF_GO_RUNTIME(GCWRITEBARRIER, "runtime.gcWriteBarrier", - P2(POINTER, POINTER), R0()) + P2(POINTER, UINTPTR), R0()) // Set *dst = *src for an arbitrary type. DEF_GO_RUNTIME(TYPEDMEMMOVE, "runtime.typedmemmove", diff --git a/gcc/go/gofrontend/wb.cc b/gcc/go/gofrontend/wb.cc index 8620e40..04619d3 100644 --- a/gcc/go/gofrontend/wb.cc +++ b/gcc/go/gofrontend/wb.cc @@ -664,11 +664,19 @@ Gogo::write_barrier_variable() { Location bloc = Linemap::predeclared_location(); - // We pretend that writeBarrier is a uint32, so that we do a - // 32-bit load. That is what the gc toolchain does. - Type* uint32_type = Type::lookup_integer_type("uint32"); - Variable* var = new Variable(uint32_type, NULL, true, false, false, - bloc); + Type* bool_type = Type::lookup_bool_type(); + Array_type* pad_type = Type::make_array_type(this->lookup_global("byte")->type_value(), + Expression::make_integer_ul(3, NULL, bloc)); + Type* uint64_type = Type::lookup_integer_type("uint64"); + Type* wb_type = Type::make_builtin_struct_type(5, + "enabled", bool_type, + "pad", pad_type, + "needed", bool_type, + "cgo", bool_type, + "alignme", uint64_type); + + Variable* var = new Variable(wb_type, NULL, + true, false, false, bloc); bool add_to_globals; Package* package = this->add_imported_package("runtime", "_", false, @@ -850,8 +858,12 @@ Gogo::assign_with_write_barrier(Function* function, Block* enclosing, case Type::TYPE_FUNCTION: case Type::TYPE_MAP: case Type::TYPE_CHANNEL: - // These types are all represented by a single pointer. - call = Runtime::make_call(Runtime::GCWRITEBARRIER, loc, 2, lhs, rhs); + { + // These types are all represented by a single pointer. + Type* uintptr_type = Type::lookup_integer_type("uintptr"); + rhs = Expression::make_unsafe_cast(uintptr_type, rhs, loc); + call = Runtime::make_call(Runtime::GCWRITEBARRIER, loc, 2, lhs, rhs); + } break; case Type::TYPE_STRING: @@ -882,7 +894,17 @@ Gogo::check_write_barrier(Block* enclosing, Statement* without, { Location loc = without->location(); Named_object* wb = this->write_barrier_variable(); + // We pretend that writeBarrier is a uint32, so that we do a + // 32-bit load. That is what the gc toolchain does. + Type* void_type = Type::make_void_type(); + Type* unsafe_pointer_type = Type::make_pointer_type(void_type); + Type* uint32_type = Type::lookup_integer_type("uint32"); + Type* puint32_type = Type::make_pointer_type(uint32_type); Expression* ref = Expression::make_var_reference(wb, loc); + ref = Expression::make_unary(OPERATOR_AND, ref, loc); + ref = Expression::make_cast(unsafe_pointer_type, ref, loc); + ref = Expression::make_cast(puint32_type, ref, loc); + ref = Expression::make_unary(OPERATOR_MULT, ref, loc); Expression* zero = Expression::make_integer_ul(0, ref->type(), loc); Expression* cond = Expression::make_binary(OPERATOR_EQEQ, ref, zero, loc); |