diff options
author | Ian Lance Taylor <iant@golang.org> | 2022-02-04 19:59:59 -0800 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2022-02-08 20:08:09 -0800 |
commit | 3ab49b1c822cf8c5748fa4de0ac970c948de6f8a (patch) | |
tree | 0696141de5cddb0755c91ff21befd313bf0b9e29 /gcc/go/gofrontend/expressions.cc | |
parent | e52a683170877d140eebc9782731eaf11897db71 (diff) | |
download | gcc-3ab49b1c822cf8c5748fa4de0ac970c948de6f8a.zip gcc-3ab49b1c822cf8c5748fa4de0ac970c948de6f8a.tar.gz gcc-3ab49b1c822cf8c5748fa4de0ac970c948de6f8a.tar.bz2 |
compiler, internal/abi: implement FuncPCABI0, FuncPCABIInternal
The Go 1.18 standard library uses an internal/abi package with two
functions that are implemented in the compiler. This patch implements
them in the gofrontend, to support the upcoming update to 1.18.
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/383514
Diffstat (limited to 'gcc/go/gofrontend/expressions.cc')
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 7970282..1e6890a 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -12177,6 +12177,50 @@ Call_expression::intrinsify(Gogo* gogo, return Runtime::make_call(code, loc, 3, a1, a2, a3); } } + else if (package == "internal/abi") + { + if ((name == "FuncPCABI0" || name == "FuncPCABIInternal") + && this->args_ != NULL + && this->args_->size() == 1) + { + // We expect to see a conversion from the expression to "any". + Expression* expr = this->args_->front(); + Type_conversion_expression* tce = expr->conversion_expression(); + if (tce != NULL) + expr = tce->expr(); + Func_expression* fe = expr->func_expression(); + Interface_field_reference_expression* interface_method = + expr->interface_field_reference_expression(); + if (fe != NULL) + { + Named_object* no = fe->named_object(); + Expression* ref = Expression::make_func_code_reference(no, loc); + Type* uintptr_type = Type::lookup_integer_type("uintptr"); + return Expression::make_cast(uintptr_type, ref, loc); + } + else if (interface_method != NULL) + return interface_method->get_function(); + else + { + expr = this->args_->front(); + go_assert(expr->type()->interface_type() != NULL + && expr->type()->interface_type()->is_empty()); + expr = Expression::make_interface_info(expr, + INTERFACE_INFO_OBJECT, + loc); + // Trust that this is a function type, which means that + // it is a direct iface type and we can use EXPR + // directly. The backend representation of this + // function is a pointer to a struct whose first field + // is the actual function to call. + Type* pvoid = Type::make_pointer_type(Type::make_void_type()); + Type* pfntype = Type::make_pointer_type(pvoid); + Expression* ref = make_unsafe_cast(pfntype, expr, loc); + return Expression::make_dereference(ref, NIL_CHECK_NOT_NEEDED, + loc); + } + } + } return NULL; } |