From cb760f66e0b29f09af5cfa0cd6aebc02aaaa0f7f Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 21 Jun 2023 14:27:02 -0700 Subject: compiler: determine types of Slice_{value,info} expressions This fixes an accidental omission in the determine types pass. Test case is https://go.dev/cl/505015. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/504797 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 10 ++++++++++ gcc/go/gofrontend/expressions.h | 5 ++--- 3 files changed, 13 insertions(+), 4 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index dbb2d68..a028350 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -6a1d165c2218cd127ee937a1f45599075762f716 +195060166e6045408a2cb95e6aa88c6f0b98f20b 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 4ac55af..2112de6 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -18307,6 +18307,16 @@ Slice_value_expression::do_traverse(Traverse* traverse) return TRAVERSE_CONTINUE; } +// Determine type of a slice value. + +void +Slice_value_expression::do_determine_type(const Type_context*) +{ + this->valmem_->determine_type_no_context(); + this->len_->determine_type_no_context(); + this->cap_->determine_type_no_context(); +} + Expression* Slice_value_expression::do_copy() { diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index 3d7e787..bdb7ccd 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -4364,8 +4364,7 @@ class Slice_value_expression : public Expression { return this->type_; } void - do_determine_type(const Type_context*) - { } + do_determine_type(const Type_context*); Expression* do_copy(); @@ -4419,7 +4418,7 @@ class Slice_info_expression : public Expression void do_determine_type(const Type_context*) - { } + { this->slice_->determine_type_no_context(); } Expression* do_copy() -- cgit v1.1 From b76cd1ec361712e1ac9ca5e0246da24ea2b78916 Mon Sep 17 00:00:00 2001 From: "Paul E. Murphy" Date: Thu, 22 Jun 2023 17:53:46 -0500 Subject: go: Update usage of TARGET_AIX to TARGET_AIX_OS TARGET_AIX is defined to a non-zero value on linux and maybe other powerpc64le targets. This leads to unexpected behavior such as dropping the .go_export section when linking a shared library on linux/powerpc64le. Instead, use TARGET_AIX_OS to toggle AIX specific behavior. Fixes golang/go#60798. 2023-06-22 Paul E. Murphy gcc/go/ * go-backend.cc [TARGET_AIX]: Rename and update usage to TARGET_AIX_OS. * go-lang.cc: Likewise. --- gcc/go/go-backend.cc | 6 +++--- gcc/go/go-lang.cc | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/go-backend.cc b/gcc/go/go-backend.cc index c6a1a2b..6e2c919 100644 --- a/gcc/go/go-backend.cc +++ b/gcc/go/go-backend.cc @@ -45,8 +45,8 @@ along with GCC; see the file COPYING3. If not see #define GO_EXPORT_SECTION_NAME ".go_export" #endif -#ifndef TARGET_AIX -#define TARGET_AIX 0 +#ifndef TARGET_AIX_OS +#define TARGET_AIX_OS 0 #endif /* This file holds all the cases where the Go frontend needs @@ -107,7 +107,7 @@ go_write_export_data (const char *bytes, unsigned int size) { gcc_assert (targetm_common.have_named_sections); sec = get_section (GO_EXPORT_SECTION_NAME, - TARGET_AIX ? SECTION_EXCLUDE : SECTION_DEBUG, + TARGET_AIX_OS ? SECTION_EXCLUDE : SECTION_DEBUG, NULL); } diff --git a/gcc/go/go-lang.cc b/gcc/go/go-lang.cc index b6e8c37..c6c147b 100644 --- a/gcc/go/go-lang.cc +++ b/gcc/go/go-lang.cc @@ -39,8 +39,8 @@ along with GCC; see the file COPYING3. If not see #include "go-c.h" #include "go-gcc.h" -#ifndef TARGET_AIX -#define TARGET_AIX 0 +#ifndef TARGET_AIX_OS +#define TARGET_AIX_OS 0 #endif /* Language-dependent contents of a type. */ @@ -116,9 +116,9 @@ go_langhook_init (void) args.compiling_runtime = go_compiling_runtime; args.debug_escape_level = go_debug_escape_level; args.debug_escape_hash = go_debug_escape_hash; - args.nil_check_size_threshold = TARGET_AIX ? -1 : 4096; + args.nil_check_size_threshold = TARGET_AIX_OS ? -1 : 4096; args.debug_optimization = go_debug_optimization; - args.need_eqtype = TARGET_AIX ? true : false; + args.need_eqtype = TARGET_AIX_OS ? true : false; args.linemap = go_get_linemap(); args.backend = go_get_backend(); go_create_gogo (&args); -- cgit v1.1 From 270742ceb5141db498ef63373512ed071923b940 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Fri, 23 Jun 2023 00:16:38 +0000 Subject: Daily bump. --- gcc/go/ChangeLog | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'gcc/go') diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 507e2d3..931c3be 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,8 @@ +2023-06-22 Paul E. Murphy + + * go-backend.cc [TARGET_AIX]: Rename and update usage to TARGET_AIX_OS. + * go-lang.cc: Likewise. + 2023-03-24 Jakub Jelinek PR middle-end/109258 -- cgit v1.1 From 6b724427aa1ec9b690e40f5206572f57e1adeda8 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 21 Jun 2023 17:27:39 -0700 Subject: compiler, libgo: support bootstrapping gc compiler In the Go 1.21 release the package internal/profile imports internal/lazyregexp. That works when bootstrapping with Go 1.17, because that compiler has internal/lazyregep and permits importing it. We also have internal/lazyregexp in libgo, but since it is not installed it is not available for importing. This CL adds internal/lazyregexp to the list of internal packages that are installed for bootstrapping. The Go 1.21, and earlier, releases have a couple of functions in the internal/abi package that are always fully intrinsified. The gofrontend recognizes and intrinsifies those functions as well. However, the gofrontend was also building function descriptors for references to the functions without calling them, which failed because there was nothing to refer to. That is OK for the gc compiler, which guarantees that the functions are only called, not referenced. This CL arranges to not generate function descriptors for these functions. For golang/go#60913 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/504798 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 3 ++- gcc/go/gofrontend/gogo.cc | 31 ++++++++++++++++++++++++++++++- 3 files changed, 33 insertions(+), 3 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index a028350..ff07b1a 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -195060166e6045408a2cb95e6aa88c6f0b98f20b +68a756b6aadc901534cfddddad2b1e73fae9e34f 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 2112de6..d276bd8 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -12272,7 +12272,8 @@ Call_expression::intrinsify(Gogo* gogo, return Runtime::make_call(code, loc, 3, a1, a2, a3); } } - else if (package == "internal/abi") + else if (package == "internal/abi" + || package == "bootstrap/internal/abi") // for bootstrapping gc { if (is_method) return NULL; diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 9197eef..980db1e 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -3296,6 +3296,9 @@ class Create_function_descriptors : public Traverse int expression(Expression**); + static bool + skip_descriptor(Gogo* gogo, const Named_object*); + private: Gogo* gogo_; }; @@ -3306,6 +3309,9 @@ class Create_function_descriptors : public Traverse int Create_function_descriptors::function(Named_object* no) { + if (Create_function_descriptors::skip_descriptor(this->gogo_, no)) + return TRAVERSE_CONTINUE; + if (no->is_function() && no->func_value()->enclosing() == NULL && !no->func_value()->is_method() @@ -3393,6 +3399,28 @@ Create_function_descriptors::expression(Expression** pexpr) return TRAVERSE_CONTINUE; } +// The gc compiler has some special cases that it always compiles as +// intrinsics. For those we don't want to generate a function +// descriptor, as there will be no code for it to refer to. + +bool +Create_function_descriptors::skip_descriptor(Gogo* gogo, + const Named_object* no) +{ + const std::string& pkgpath(no->package() == NULL + ? gogo->pkgpath() + : no->package()->pkgpath()); + + // internal/abi is the standard library package, + // bootstrap/internal/abi is the name used when bootstrapping the gc + // compiler. + + return ((pkgpath == "internal/abi" + || pkgpath == "bootstrap/internal/abi") + && (no->name() == "FuncPCABI0" + || no->name() == "FuncPCABIInternal")); +} + // Create function descriptors as needed. We need a function // descriptor for all exported functions and for all functions that // are referenced without being called. @@ -3414,7 +3442,8 @@ Gogo::create_function_descriptors() if (no->is_function_declaration() && !no->func_declaration_value()->type()->is_method() && !Linemap::is_predeclared_location(no->location()) - && !Gogo::is_hidden_name(no->name())) + && !Gogo::is_hidden_name(no->name()) + && !Create_function_descriptors::skip_descriptor(this, no)) fndecls.push_back(no); } for (std::vector::const_iterator p = fndecls.begin(); -- cgit v1.1 From 3a39a31b8ae9c6465434aefa657f7fcc86f905c0 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sun, 25 Jun 2023 20:16:01 -0700 Subject: compiler: support -fgo-importcfg * lang.opt (fgo-importcfg): New option. * go-c.h (struct go_create_gogo_args): Add importcfg field. * go-lang.cc (go_importcfg): New static variable. (go_langhook_init): Set args.importcfg. (go_langhook_handle_option): Handle -fgo-importcfg. * gccgo.texi (Invoking gccgo): Document -fgo-importcfg. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/506095 --- gcc/go/gccgo.texi | 8 +++ gcc/go/go-c.h | 1 + gcc/go/go-lang.cc | 6 +++ gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/embed.cc | 11 ++-- gcc/go/gofrontend/go.cc | 2 + gcc/go/gofrontend/gogo.cc | 19 ++++++- gcc/go/gofrontend/gogo.h | 12 +++++ gcc/go/gofrontend/import.cc | 124 ++++++++++++++++++++++++++++++++++++++++++++ gcc/go/lang.opt | 4 ++ 10 files changed, 182 insertions(+), 7 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gccgo.texi b/gcc/go/gccgo.texi index 4ab1a76..90651af 100644 --- a/gcc/go/gccgo.texi +++ b/gcc/go/gccgo.texi @@ -271,6 +271,14 @@ pattern to a list of file names, and @code{Files} maps each file name to a full path to the file. This option is intended for use by the @command{go} command to implement @code{//go:embed}. +@cindex @option{-fgo-importcfg} +@item -fgo-importcfg=@var{file} +Identify a file that provides mappings for import package paths found +in the Go source files. The file can contain two commands: +@code{importpath} to rename import paths for vendoring and +@code{packagefile} to map from package path to files containing export +data. This option is intended for use by the @command{go} command. + @cindex @option{-g for gccgo} @item -g This is the standard @command{gcc} option (@pxref{Debugging Options, , diff --git a/gcc/go/go-c.h b/gcc/go/go-c.h index c605038..6a2b57b 100644 --- a/gcc/go/go-c.h +++ b/gcc/go/go-c.h @@ -41,6 +41,7 @@ struct go_create_gogo_args const char* prefix; const char* relative_import_path; const char* c_header; + const char* importcfg; const char* embedcfg; Backend* backend; Linemap* linemap; diff --git a/gcc/go/go-lang.cc b/gcc/go/go-lang.cc index c6c147b..e85a4bf 100644 --- a/gcc/go/go-lang.cc +++ b/gcc/go/go-lang.cc @@ -90,6 +90,7 @@ static const char *go_prefix = NULL; static const char *go_relative_import_path = NULL; static const char *go_c_header = NULL; static const char *go_embedcfg = NULL; +static const char *go_importcfg = NULL; /* Language hooks. */ @@ -111,6 +112,7 @@ go_langhook_init (void) args.relative_import_path = go_relative_import_path; args.c_header = go_c_header; args.embedcfg = go_embedcfg; + args.importcfg = go_importcfg; args.check_divide_by_zero = go_check_divide_zero; args.check_divide_overflow = go_check_divide_overflow; args.compiling_runtime = go_compiling_runtime; @@ -286,6 +288,10 @@ go_langhook_handle_option ( go_embedcfg = arg; break; + case OPT_fgo_importcfg_: + go_importcfg = arg; + break; + default: /* Just return 1 to indicate that the option is valid. */ break; diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index ff07b1a..c44cdc2 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -68a756b6aadc901534cfddddad2b1e73fae9e34f +92152c88ea8e2dd9e8c67e91bf4ae5e3edf1b506 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/embed.cc b/gcc/go/gofrontend/embed.cc index 0584f70..6dada5e 100644 --- a/gcc/go/gofrontend/embed.cc +++ b/gcc/go/gofrontend/embed.cc @@ -19,8 +19,8 @@ // Read a file into *DATA. Returns false on error. -static bool -read_file(const char* filename, Location loc, std::string* data) +bool +Gogo::read_file(const char* filename, Location loc, std::string* data) { int fd = open(filename, O_RDONLY | O_BINARY); if (fd < 0) @@ -346,7 +346,8 @@ Gogo::read_embedcfg(const char *filename) bool Embedcfg_reader::initialize_from_file() { - if (!read_file(this->filename_, Linemap::unknown_location(), &this->data_)) + if (!Gogo::read_file(this->filename_, Linemap::unknown_location(), + &this->data_)) return false; if (this->data_.empty()) { @@ -849,7 +850,7 @@ Gogo::initializer_for_embeds(Type* type, } std::string data; - if (!read_file(this->embed_files_[paths[0]].c_str(), loc, &data)) + if (!Gogo::read_file(this->embed_files_[paths[0]].c_str(), loc, &data)) return Expression::make_error(loc); Expression* e = Expression::make_string(data, loc); @@ -909,7 +910,7 @@ Gogo::initializer_for_embeds(Type* type, std::string data; if ((*pp)[pp->size() - 1] != '/') { - if (!read_file(this->embed_files_[*pp].c_str(), loc, &data)) + if (!Gogo::read_file(this->embed_files_[*pp].c_str(), loc, &data)) return Expression::make_error(loc); } diff --git a/gcc/go/gofrontend/go.cc b/gcc/go/gofrontend/go.cc index 1512770..66d4816 100644 --- a/gcc/go/gofrontend/go.cc +++ b/gcc/go/gofrontend/go.cc @@ -40,6 +40,8 @@ go_create_gogo(const struct go_create_gogo_args* args) ::gogo->set_compiling_runtime(args->compiling_runtime); if (args->c_header != NULL) ::gogo->set_c_header(args->c_header); + if (args->importcfg != NULL) + ::gogo->read_importcfg(args->importcfg); if (args->embedcfg != NULL) ::gogo->read_embedcfg(args->embedcfg); ::gogo->set_debug_escape_level(args->debug_escape_level); diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 980db1e..fa3cd6e 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -52,6 +52,10 @@ Gogo::Gogo(Backend* backend, Linemap* linemap, int, int pointer_size) prefix_from_option_(false), relative_import_path_(), c_header_(), + import_map_(), + package_file_(), + embed_patterns_(), + embed_files_(), check_divide_by_zero_(true), check_divide_overflow_(true), compiling_runtime_(false), @@ -517,7 +521,20 @@ Gogo::import_package(const std::string& filename, return; } - Import::Stream* stream = Import::open_package(filename, location, + // If we are using an importcfg file we have to check two mappings. + // IMPORT_MAP_ is a mapping from package path to real package path, + // for vendoring. PACKAGE_FILE_ is a mapping from package path to + // file name, to find the file in the build cache. + std::string path = filename; + Unordered_map(std::string, std::string)::const_iterator pi; + pi = this->import_map_.find(filename); + if (pi != this->import_map_.end()) + path = pi->second; + pi = this->package_file_.find(path); + if (pi != this->package_file_.end()) + path = pi->second; + + Import::Stream* stream = Import::open_package(path, location, this->relative_import_path_); if (stream == NULL) { diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index c08a16b..4fd45bf 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -393,6 +393,10 @@ class Gogo set_c_header(const std::string& s) { this->c_header_ = s; } + // Read an importcfg file. + void + read_importcfg(const char* filename); + // Read an embedcfg file. void read_embedcfg(const char* filename); @@ -1126,6 +1130,10 @@ class Gogo static size_t special_name_pos(const std::string& name); + // Read a file into memory. + static bool + read_file(const char* filename, Location loc, std::string* data); + private: // During parsing, we keep a stack of functions. Each function on // the stack is one that we are currently parsing. For each @@ -1295,6 +1303,10 @@ class Gogo std::string relative_import_path_; // The C header file to write, from the -fgo-c-header option. std::string c_header_; + // Mapping from imports in the source file to the real import paths. + Unordered_map(std::string, std::string) import_map_; + // Mapping from import paths to files to read. + Unordered_map(std::string, std::string) package_file_; // Patterns from an embedcfg file. Embed_patterns embed_patterns_; // Mapping from file to full path from an embedcfg file. diff --git a/gcc/go/gofrontend/import.cc b/gcc/go/gofrontend/import.cc index 6a5491b..21691fa 100644 --- a/gcc/go/gofrontend/import.cc +++ b/gcc/go/gofrontend/import.cc @@ -34,6 +34,130 @@ go_add_search_path(const char* path) search_path.push_back(std::string(path)); } +// Read an importcfg file. + +void +Gogo::read_importcfg(const char* filename) +{ + std::string data; + if (!Gogo::read_file(filename, Linemap::unknown_location(), &data)) + return; + const char* p = data.data(); + const char* pend = p + data.length(); + int lineno = 0; + const char *pnext = NULL; + for (; p < pend; p = pnext) + { + // Line numbers start at 1. + lineno++; + + // Find end of line. + const char* pnl = static_cast(memchr(p, '\n', pend - p)); + if (pnl != NULL) + pnext = pnl + 1; + else + { + pnl = pend; + pnext = pnl; + } + + // Trim leading spaces. + while (p < pnl) + { + unsigned int rune; + int rune_len = Lex::fetch_char(p, &rune); + if (rune_len == 0) + { + go_error_at(Linemap::unknown_location(), + "%s:%d: invalid character in importcfg file", + filename, lineno); + return; + } + if (!Lex::is_unicode_space(rune)) + break; + p += rune_len; + } + + // Trim trailing spaces. + while (pnl > p) + { + size_t start = pnl - p - 1; + unsigned int rune = (unsigned char)p[start]; + int rune_len = 1; + if (rune > 0x7f) + { + for (start--; start > 0; start--) + { + unsigned char c = p[start]; + if ((c & 0xc0) != 0x80) + break; + } + rune_len = Lex::fetch_char(p + start, &rune); + if (static_cast(rune_len) != (pnl - p) - start) + { + go_error_at(Linemap::unknown_location(), + "%s:%d: invalid character in importcfg file", + filename, lineno); + return; + } + } + if (!Lex::is_unicode_space(rune)) + break; + pnl -= rune_len; + } + + // Skip empty lines and comment lines. + if (p == pnl || *p == '#') + continue; + + size_t verb_len; + const char* psp = static_cast(memchr(p, ' ', pnl - p)); + if (psp == NULL) + verb_len = pnl - p; + else + verb_len = psp - p; + + bool importmap = false; + bool packagefile = false; + if (strncmp(p, "importmap", verb_len) == 0) + importmap = true; + else if (strncmp(p, "packagefile", verb_len) == 0) + packagefile = true; + else + { + go_error_at(Linemap::unknown_location(), + "%s:%d: unknown directive in importcfg file", + filename, lineno); + return; + } + + const char* peq; + if (psp == NULL) + peq = NULL; + else + { + psp++; + peq = static_cast(memchr(psp, '=', pnl - psp)); + } + if (peq == NULL || peq + 1 == pnl) + { + go_error_at(Linemap::unknown_location(), + "%s:%d: invalid syntax in importcfg file", + filename, lineno); + return; + } + + std::string first(psp, peq - psp); + std::string second(peq + 1, pnl - (peq + 1)); + if (importmap) + this->import_map_[first] = second; + else if (packagefile) + this->package_file_[first] = second; + else + go_unreachable(); + } +} + // Find import data. This searches the file system for FILENAME and // returns a pointer to a Stream object to read the data that it // exports. If the file is not found, it returns NULL. diff --git a/gcc/go/lang.opt b/gcc/go/lang.opt index 4ca989c..0d658fc 100644 --- a/gcc/go/lang.opt +++ b/gcc/go/lang.opt @@ -61,6 +61,10 @@ fgo-embedcfg= Go Joined RejectNegative -fgo-embedcfg= List embedded files via go:embed. +fgo-importcfg= +Go Joined RejectNegative +-fgo-importcfg= Provide file that tells where to find imports. + fgo-optimize- Go Joined -fgo-optimize- Turn on optimization passes in the frontend. -- cgit v1.1