diff options
author | Martin Liska <mliska@suse.cz> | 2021-08-09 11:14:45 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2021-08-09 11:14:45 +0200 |
commit | 9207fa3effc9970d9e2a48993adbfc34c08a8f65 (patch) | |
tree | 460892004407fca4c097ec65831d468e61fca54f /gcc/go | |
parent | 01c909e1a5fca4988431a328454e9d8c0eea9ef6 (diff) | |
parent | a5e3c1e2c8dafcd2f6e4eeb2b2fa38fd40c5eda3 (diff) | |
download | gcc-9207fa3effc9970d9e2a48993adbfc34c08a8f65.zip gcc-9207fa3effc9970d9e2a48993adbfc34c08a8f65.tar.gz gcc-9207fa3effc9970d9e2a48993adbfc34c08a8f65.tar.bz2 |
Merge branch 'master' into devel/sphinx
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/escape.cc | 47 | ||||
-rw-r--r-- | gcc/go/gofrontend/export.cc | 44 | ||||
-rw-r--r-- | gcc/go/gofrontend/export.h | 10 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 8 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.h | 21 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.h | 4 | ||||
-rw-r--r-- | gcc/go/gofrontend/import.cc | 6 | ||||
-rw-r--r-- | gcc/go/gofrontend/unsafe.cc | 64 |
9 files changed, 176 insertions, 30 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 19ab2de..b983fda 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -32590102c464679f845667b5554e1dcce2549ad2 +d5d51242efc432fa62d4e9b141b01c280af32d19 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/escape.cc b/gcc/go/gofrontend/escape.cc index c8978ac..6da29ed 100644 --- a/gcc/go/gofrontend/escape.cc +++ b/gcc/go/gofrontend/escape.cc @@ -1646,6 +1646,7 @@ Escape_analysis_assign::expression(Expression** pexpr) case Runtime::MAKECHAN: case Runtime::MAKECHAN64: case Runtime::MAKEMAP: + case Runtime::MAKEMAP64: case Runtime::MAKESLICE: case Runtime::MAKESLICE64: this->context_->track(n); @@ -1705,8 +1706,52 @@ Escape_analysis_assign::expression(Expression** pexpr) } break; + case Runtime::MEMCMP: + case Runtime::DECODERUNE: + case Runtime::INTSTRING: + case Runtime::MAKEMAP_SMALL: + case Runtime::MAPACCESS1: + case Runtime::MAPACCESS1_FAST32: + case Runtime::MAPACCESS1_FAST64: + case Runtime::MAPACCESS1_FASTSTR: + case Runtime::MAPACCESS1_FAT: + case Runtime::MAPACCESS2: + case Runtime::MAPACCESS2_FAST32: + case Runtime::MAPACCESS2_FAST64: + case Runtime::MAPACCESS2_FASTSTR: + case Runtime::MAPACCESS2_FAT: + case Runtime::MAPASSIGN_FAST32: + case Runtime::MAPASSIGN_FAST64: + case Runtime::MAPITERINIT: + case Runtime::MAPITERNEXT: + case Runtime::MAPCLEAR: + case Runtime::CHANRECV2: + case Runtime::SELECTGO: + case Runtime::SELECTNBSEND: + case Runtime::SELECTNBRECV: + case Runtime::BLOCK: + case Runtime::IFACET2IP: + case Runtime::EQTYPE: + case Runtime::MEMCLRHASPTR: + case Runtime::FIELDTRACK: + case Runtime::BUILTIN_MEMSET: + case Runtime::PANIC_SLICE_CONVERT: + // these do not escape. + break; + + case Runtime::IFACEE2E2: + case Runtime::IFACEI2E2: + case Runtime::IFACEE2I2: + case Runtime::IFACEI2I2: + case Runtime::IFACEE2T2P: + case Runtime::IFACEI2T2P: + // handled in ::assign. + break; + default: - break; + // should not see other runtime calls. they are not yet + // lowered to runtime calls at this point. + go_unreachable(); } } else diff --git a/gcc/go/gofrontend/export.cc b/gcc/go/gofrontend/export.cc index e99c680..3d11334 100644 --- a/gcc/go/gofrontend/export.cc +++ b/gcc/go/gofrontend/export.cc @@ -106,11 +106,12 @@ class Collect_export_references : public Traverse { public: Collect_export_references(Export* exp, + const std::map<std::string, Package*>& packages, Unordered_set(Named_object*)* exports, Unordered_set(const Package*)* imports) : Traverse(traverse_expressions | traverse_types), - exp_(exp), exports_(exports), imports_(imports), + exp_(exp), packages_(packages), exports_(exports), imports_(imports), inline_fcn_worklist_(NULL), exports_finalized_(false) { } @@ -150,6 +151,8 @@ class Collect_export_references : public Traverse // The exporter. Export* exp_; + // The list of packages known to this compilation. + const std::map<std::string, Package*>& packages_; // The set of named objects to export. Unordered_set(Named_object*)* exports_; // Set containing all directly and indirectly imported packages. @@ -257,6 +260,24 @@ Collect_export_references::expression(Expression** pexpr) return TRAVERSE_CONTINUE; } + const Call_expression* call = expr->call_expression(); + if (call != NULL) + { + const Builtin_call_expression* bce = call->builtin_call_expression(); + if (bce != NULL + && (bce->code() == Builtin_call_expression::BUILTIN_ADD + || bce->code() == Builtin_call_expression::BUILTIN_SLICE)) + { + // This is a reference to unsafe.Add or unsafe.Slice. Make + // sure we list the "unsafe" package in the imports and give + // it a package index. + const std::map<std::string, Package*>::const_iterator p = + this->packages_.find("unsafe"); + go_assert(p != this->packages_.end()); + this->imports_->insert(p->second); + } + } + return TRAVERSE_CONTINUE; } @@ -589,7 +610,7 @@ Export::export_globals(const std::string& package_name, // Track all imported packages mentioned in export data. Unordered_set(const Package*) all_imports; - Collect_export_references collect(this, &exports, &all_imports); + Collect_export_references collect(this, packages, &exports, &all_imports); // Walk the set of inlinable routine bodies collected above. This // can potentially expand the exports set. @@ -1274,6 +1295,25 @@ Export::package_index(const Package* pkg) const return index; } +// Return the index of the "unsafe" package. + +int +Export::unsafe_package_index() const +{ + for (Unordered_map(const Package*, int)::const_iterator p = + this->packages_.begin(); + p != this->packages_.end(); + ++p) + { + if (p->first->pkgpath() == "unsafe") + { + go_assert(p->second != 0); + return p->second; + } + } + go_unreachable(); +} + // Return the index of a type. int diff --git a/gcc/go/gofrontend/export.h b/gcc/go/gofrontend/export.h index c93bced..1f61343 100644 --- a/gcc/go/gofrontend/export.h +++ b/gcc/go/gofrontend/export.h @@ -216,6 +216,11 @@ class Export : public String_dump int package_index(const Package* p) const; + // Return the index of the "unsafe" package, which must be one of + // the exported packages. + int + unsafe_package_index() const; + private: Export(const Export&); Export& operator=(const Export&); @@ -377,6 +382,11 @@ class Export_function_body : public String_dump package_index(const Package* p) const { return this->exp_->package_index(p); } + // Return the index of the "unsafe" package. + int + unsafe_package_index() const + { return this->exp_->unsafe_package_index(); } + // Record a temporary statement and return its index. unsigned int record_temporary(const Temporary_statement*); diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 33177a7..f462b0e 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -11039,6 +11039,14 @@ Builtin_call_expression::do_export(Export_function_body* efb) const // A trailing space lets us reliably identify the end of the number. efb->write_c_string(" "); } + else if (this->code_ == BUILTIN_ADD || this->code_ == BUILTIN_SLICE) + { + char buf[50]; + snprintf(buf, sizeof buf, "<p%d>%s", efb->unsafe_package_index(), + (this->code_ == BUILTIN_ADD ? "Add" : "Slice")); + efb->write_c_string(buf); + this->export_arguments(efb); + } else { const char *s = NULL; diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index 79a8785..9f8f4e9 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -732,6 +732,10 @@ class Expression call_expression() { return this->convert<Call_expression, EXPRESSION_CALL>(); } + const Call_expression* + call_expression() const + { return this->convert<const Call_expression, EXPRESSION_CALL>(); } + // If this is a call_result expression, return the Call_result_expression // structure. Otherwise, return NULL. This is a controlled dynamic // cast. @@ -2460,13 +2464,16 @@ class Call_expression : public Expression // Whether this is a call to builtin function. virtual bool - is_builtin() + is_builtin() const { return false; } // Convert to a Builtin_call_expression, or return NULL. inline Builtin_call_expression* builtin_call_expression(); + inline const Builtin_call_expression* + builtin_call_expression() const; + protected: int do_traverse(Traverse*); @@ -2625,12 +2632,12 @@ class Builtin_call_expression : public Call_expression }; Builtin_function_code - code() + code() const { return this->code_; } // This overrides Call_expression::is_builtin. bool - is_builtin() + is_builtin() const { return true; } // Return whether EXPR, of array type, is a constant if passed to @@ -2726,6 +2733,14 @@ Call_expression::builtin_call_expression() : NULL); } +inline const Builtin_call_expression* +Call_expression::builtin_call_expression() const +{ + return (this->is_builtin() + ? static_cast<const Builtin_call_expression*>(this) + : NULL); +} + // A single result from a call which returns multiple results. class Call_result_expression : public Expression diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index c49bc92..9ffd120 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -533,6 +533,10 @@ class Gogo register_package(const std::string& pkgpath, const std::string& pkgpath_symbol, Location); + // Add the unsafe bindings to the unsafe package. + void + add_unsafe_bindings(Package*); + // Look up a package by pkgpath, and return its pkgpath_symbol. std::string pkgpath_symbol_for_package(const std::string&); diff --git a/gcc/go/gofrontend/import.cc b/gcc/go/gofrontend/import.cc index f671416..6a5491b 100644 --- a/gcc/go/gofrontend/import.cc +++ b/gcc/go/gofrontend/import.cc @@ -497,6 +497,9 @@ Import::read_one_import() p->set_package_name(package_name, this->location()); this->packages_.push_back(p); + + if (pkgpath == "unsafe") + this->gogo_->add_unsafe_bindings(p); } // Read an indirectimport line. @@ -515,6 +518,9 @@ Import::read_one_indirect_import() p->set_package_name(package_name, this->location()); this->packages_.push_back(p); + + if (pkgpath == "unsafe") + this->gogo_->add_unsafe_bindings(p); } // Read the list of import control functions and/or init graph. diff --git a/gcc/go/gofrontend/unsafe.cc b/gcc/go/gofrontend/unsafe.cc index 18bd99e..c4a9346 100644 --- a/gcc/go/gofrontend/unsafe.cc +++ b/gcc/go/gofrontend/unsafe.cc @@ -10,15 +10,12 @@ #include "types.h" #include "gogo.h" -// Set up the builtin unsafe package. This should probably be driven -// by a table. +// Set up the builtin unsafe package. void Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported, Location location) { - Location bloc = Linemap::predeclared_location(); - bool add_to_globals; Package* package = this->add_imported_package("unsafe", local_name, is_local_name_exported, @@ -34,10 +31,40 @@ Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported, package->set_location(location); this->imports_.insert(std::make_pair("unsafe", package)); + this->add_unsafe_bindings(package); + + Named_object* pointer_no = package->bindings()->lookup_local("Pointer"); + pointer_no->type_value()->set_is_visible(); + + if (add_to_globals) + { + Bindings* bindings = package->bindings(); + for (Bindings::const_declarations_iterator p = + bindings->begin_declarations(); + p != bindings->end_declarations(); + ++p) + this->add_dot_import_object(p->second); + } +} + +// Add the unsafe bindings to the Package object. This should +// probably be driven by a table. + +void +Gogo::add_unsafe_bindings(Package* package) +{ Bindings* bindings = package->bindings(); + if (bindings->lookup_local("Sizeof") != NULL) + { + // Already done by an earlier import. + return; + } + + Location bloc = Linemap::predeclared_location(); + // The type may have already been created by an import. - Named_object* no = package->bindings()->lookup("Pointer"); + Named_object* no = bindings->lookup("Pointer"); if (no == NULL) { Type* type = Type::make_pointer_type(Type::make_void_type()); @@ -49,11 +76,12 @@ Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported, go_assert(no->package() == package); go_assert(no->is_type()); go_assert(no->type_value()->is_unsafe_pointer_type()); - no->type_value()->set_is_visible(); } Named_type* pointer_type = no->type_value(); - if (add_to_globals) - this->add_named_type(pointer_type); + + // This may be called during an import, so the type may not be + // visible yet. + pointer_type->clear_is_visible(); Type* uintptr_type = Type::lookup_integer_type("uintptr"); @@ -62,9 +90,7 @@ Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported, results->push_back(Typed_identifier("", uintptr_type, bloc)); Function_type* fntype = Type::make_function_type(NULL, NULL, results, bloc); fntype->set_is_builtin(); - no = bindings->add_function_declaration("Sizeof", package, fntype, bloc); - if (add_to_globals) - this->add_dot_import_object(no); + bindings->add_function_declaration("Sizeof", package, fntype, bloc); // Offsetof. results = new Typed_identifier_list; @@ -72,9 +98,7 @@ Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported, fntype = Type::make_function_type(NULL, NULL, results, bloc); fntype->set_is_varargs(); fntype->set_is_builtin(); - no = bindings->add_function_declaration("Offsetof", package, fntype, bloc); - if (add_to_globals) - this->add_dot_import_object(no); + bindings->add_function_declaration("Offsetof", package, fntype, bloc); // Alignof. results = new Typed_identifier_list; @@ -82,25 +106,19 @@ Gogo::import_unsafe(const std::string& local_name, bool is_local_name_exported, fntype = Type::make_function_type(NULL, NULL, results, bloc); fntype->set_is_varargs(); fntype->set_is_builtin(); - no = bindings->add_function_declaration("Alignof", package, fntype, bloc); - if (add_to_globals) - this->add_dot_import_object(no); + bindings->add_function_declaration("Alignof", package, fntype, bloc); // Add. results = new Typed_identifier_list; results->push_back(Typed_identifier("", pointer_type, bloc)); fntype = Type::make_function_type(NULL, NULL, results, bloc); fntype->set_is_builtin(); - no = bindings->add_function_declaration("Add", package, fntype, bloc); - if (add_to_globals) - this->add_dot_import_object(no); + bindings->add_function_declaration("Add", package, fntype, bloc); // Slice. fntype = Type::make_function_type(NULL, NULL, NULL, bloc); fntype->set_is_builtin(); - no = bindings->add_function_declaration("Slice", package, fntype, bloc); - if (add_to_globals) - this->add_dot_import_object(no); + bindings->add_function_declaration("Slice", package, fntype, bloc); if (!this->imported_unsafe_) { |