summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2017-07-28 18:03:29 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2017-07-28 18:03:29 +0000
commit687bf0c68d861017db06643b788e4bf95fe09d4f (patch)
tree331c793014022b2db3215daf49ba805b42c7133f
parent5731103c14d9676c2821fbea321434c02594a253 (diff)
downloadgcc-687bf0c68d861017db06643b788e4bf95fe09d4f.tar.gz
compiler: track placeholder pointer types for conversion
We recently started walking through the hash table of pointer types to finalize them. Unfortunately it is possible to create a new pointer type while finalizing an existing one (test case: test/fixedbugs/issue5291) and that breaks the iteration. So, instead, keep a list of placeholder pointer types, and iterate through them while permitting the list to be extended as we go. Reviewed-on: https://go-review.googlesource.com/51771 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@250683 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/types.cc15
-rw-r--r--gcc/go/gofrontend/types.h3
3 files changed, 15 insertions, 5 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 1c649cb6ca9..9dc96cfc100 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-27804ec53590e3644e030c9860822139a0cfb03f
+2118958321532352c91fd9406f571f8729a791cd
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/types.cc b/gcc/go/gofrontend/types.cc
index 91d6091f544..4d923733667 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -1057,6 +1057,8 @@ Type::get_backend_placeholder(Gogo* gogo)
{
Location loc = Linemap::unknown_location();
bt = gogo->backend()->placeholder_pointer_type("", loc, false);
+ Pointer_type* pt = this->convert<Pointer_type, TYPE_POINTER>();
+ Type::placeholder_pointers.push_back(pt);
}
break;
@@ -5521,6 +5523,11 @@ Pointer_type::do_import(Import* imp)
Type::Pointer_type_table Type::pointer_types;
+// A list of placeholder pointer types. We keep this so we can ensure
+// they are finalized.
+
+std::vector<Pointer_type*> Type::placeholder_pointers;
+
// Make a pointer type.
Pointer_type*
@@ -5551,11 +5558,11 @@ Type::make_pointer_type(Type* to_type)
void
Type::finish_pointer_types(Gogo* gogo)
{
- for (Pointer_type_table::const_iterator i = pointer_types.begin();
- i != pointer_types.end();
- ++i)
+ // We don't use begin() and end() because it is possible to add new
+ // placeholder pointer types as we finalized existing ones.
+ for (size_t i = 0; i < Type::placeholder_pointers.size(); i++)
{
- Pointer_type* pt = i->second;
+ Pointer_type* pt = Type::placeholder_pointers[i];
Type_btypes::iterator tbti = Type::type_btypes.find(pt);
if (tbti != Type::type_btypes.end() && tbti->second.is_placeholder)
{
diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h
index f659f384845..f15f08ae4f0 100644
--- a/gcc/go/gofrontend/types.h
+++ b/gcc/go/gofrontend/types.h
@@ -1350,6 +1350,9 @@ class Type
static Pointer_type_table pointer_types;
+ // List of placeholder pointer types.
+ static std::vector<Pointer_type*> placeholder_pointers;
+
// The type classification.
Type_classification classification_;
// The backend representation of the type, once it has been